[Réglé]Test à l'accès d'un fichier (savoir s'il est déjà ouvert)

Test à l'accès d'un fichier (savoir s'il est déjà ouvert) [Réglé] - C#/.NET managed - Programmation

Marsh Posté le 26-03-2009 à 14:38:42    

Bonjour à tous et toutes, je voudrais avoir votre avis sur le problème suivant:
 
J'ai une application que j'ai développé, qui concrètement ouvre un fichier texte déposé dans un répertoire et bricole avec (elle le le parcours en lecture puis le déplace notamment ).
 
Bon le problème qui se pose est le suivant:
dans le répertoire monitoré, les fichiers sont déposé via FTP.
 
Si dans mes tests je n'ai jamais eu de problème de concurence d'accès, ni en test réel avec mon collègue, durant la démo bien sûr ça c'est planté à chaque fois!
 
Je suis sûr que le problème est bien une concurence d'accès car:
Je lance le transfert ftp, le fichier est bien présent au bou mais mon application est crachée avec un message d'erreur de windows.
Si je la relance, lors du lancement elle traite tout ce qui est présent dans le répertoire, donc elle va traiter le fichier qui est présent et ne se crashera pas cette fois là. Preuve que c'est bien un accès durant le transfert du fichier via ftp qui le crash.  
Bref en gros d'après mes tests et comment ça se passe, je suis sur que c'est une concurence d'accès au fichier. (j'essaye de le lire et donc de stocker dans mes variables alors que le transfert n'est pas fini).
 
 
 
Ma question c'est comment tester donc que le fichier est bien disponible pour moi, donc qu'il est complet, en sachant que je réagis sur dépot de fichier dans le répertoire (réaction à l'évènement système de création de nouveau fichier dans ce répertoire).  
 
Un sleep n'est absolument pas possible car si la taille du fichier change ça sera le même problème, bref idéalement il faut que je boucle tant que le fichier n'est pas dispo pour moi,
 
Est ce qu'un transfert ftp est exclusif sur le fichier? Je suppose que oui, Et du coup comment savoir si le fichier est accessible en readonly? (en gros il faut que je boucle tant que le fichier n'est accessible qu'en readonly, dès qu'il est dispo en full droit alors c'est que le transfert est fini je suppose?)
 
C'est dans FileAcces ou FileAttribute? et mon idée est elle bonne?
 
en gros ça:

Code :
  1. Thread.Sleep(500);
  2.                     FileAttributes Fa = File.GetAttributes(fic);
  3.                     // Vérification si le fichier est en lecture seule
  4.                     while (Fa == FileAttributes.ReadOnly)
  5.                     {
  6.                         Thread.Sleep(500);
  7.                         Fa = File.GetAttributes(fic);
  8.                     }


Mais je ne sais pas si ici les attributs du fichiers c'est ce que je vais avoir en ouverture, ou juste les droits utilisateurs sur le fichier...
 
Merci d'avance.


Message édité par burn2 le 26-03-2009 à 17:11:25

---------------
"C'est vrai qu'un type aussi pénible de jour on serait en droit d'espérer qu'il fasse un break de nuit mais bon …"
Reply

Marsh Posté le 26-03-2009 à 14:38:42   

Reply

Marsh Posté le 26-03-2009 à 15:07:09    

Bon j'ai testé, ma fonction de test ne marche pas,
si je fais ça d'un autre côté:

Code :
  1. Console.WriteLine("Verrouillage fichiers" );
  2.             FileStream fs = new FileStream("IN/2560.txt", FileMode.Open);
  3.             Thread.Sleep(5000);
  4.             fs.Close();


pour accéder exprès au fichier qui est déposé dans le répertoire afin de le bloquer ouvert puis je lance mon programme il se plante bien (malgrès le try et catch...). Donc comment tester si le fichier n'est pas déjà ouvert?
 
(je pense qu'il doit se planter lors du déplacement malgrès le try catch dans mon cas, il aurait aussi pu se planter lors de l'affectation des variables si le fichier n'est pas complet..., mais bon ce n'est pas une solution, il faut bien que j'attende d'en avoir l'exclusivité pour le traiter et j'aimerais bien savoir comment savoir ça...)


Message édité par burn2 le 26-03-2009 à 15:13:47

---------------
"C'est vrai qu'un type aussi pénible de jour on serait en droit d'espérer qu'il fasse un break de nuit mais bon …"
Reply

Marsh Posté le 26-03-2009 à 16:15:01    

D'ailleurs je ne comprends pas pourquoi ça se plante...
 
La partie ou je déplace le fichier en question est dans un try catch, et visiblement malgrès ça ça se crash...  
 
Je me suis dit ok, j'essaye de faire une ouverture exclusive en amont avec une boucle ou j'attends de pouvoir le faire:
 

Code :
  1. private bool fileIsOpen(string file)
  2.         {
  3.             try
  4.             {
  5.                 FileStream fs;
  6.                 fs =File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
  7.                 if (fs != null)
  8.                 {
  9.                     MessageBox.Show(fs.ToString());
  10.                     fs.Close();
  11.                     return false;
  12.                 }
  13.                 else
  14.                     return true;
  15.             }
  16.             catch (InvalidCastException e)
  17.             {
  18.                 //Console.WriteLine(e.Message);
  19.                 //Thread.Sleep(1000);
  20.                 return true;
  21.             }
  22.         }


 
 
Sauf que non ça ne bloque pas si le fichier est déjà ouvert ailleurs apparement. :(


---------------
"C'est vrai qu'un type aussi pénible de jour on serait en droit d'espérer qu'il fasse un break de nuit mais bon …"
Reply

Marsh Posté le 26-03-2009 à 16:29:49    

Bon en mode débugage, je vois qu'il bloque à ma ligne de test
fs =File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
 
avec ça comme exception qu'il me dit non gérée:

Citation :


Le processus ne peut pas accéder au fichier 'T:\user\Developpement\ProgramesCSharp\execCMDV3\execCMDV2\bin\Debug\IN\2560.txt', car il est en cours d'utilisation par un autre processus


Donc il n'arrive pas à ouvrir le fichier, comme prévu, donc c'est bien ça qu'il faut que je fasse comme test, sauf que le catch ne récupère pas l'erreur!
 
 
Je fais comment moi pour tester si je peux accéder au fichier???? :( je comprend pas le try catch ne marche pas. C'est quoi ce binz.  
 
Je fais comment concrètement pour savoir si je peux accéder au fichier en mode exclusif sans l'ouvrir en mode exclusif??? :(


Message édité par burn2 le 26-03-2009 à 16:54:06

---------------
"C'est vrai qu'un type aussi pénible de jour on serait en droit d'espérer qu'il fasse un break de nuit mais bon …"
Reply

Marsh Posté le 26-03-2009 à 17:11:03    

Bon j'ai trouvé!  
Ma cause est le catch!
 
 
Donc en fait pour ne pas avoir de problème il faut que çe fasse:
 
 

Code :
  1. private bool fileIsOpen(string file)
  2.         {
  3.             try
  4.             {
  5.                 FileStream fs;
  6.                 fs =File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
  7.                 if (fs != null)
  8.                 {
  9.                     fs.Close();
  10.                     return false;
  11.                 }
  12.                 else
  13.                     return true;
  14.                 return true;
  15.             }
  16.             catch (IOException)
  17.             {
  18.                
  19.                 //Thread.Sleep(1000);
  20.                 return true;
  21.             }
  22.         }


 
ioexception et non pas ce que je mettais moi!
 
Bref ayé c'est réglé. :)


---------------
"C'est vrai qu'un type aussi pénible de jour on serait en droit d'espérer qu'il fasse un break de nuit mais bon …"
Reply

Marsh Posté le 26-04-2009 à 12:04:53    

La technique qui consiste à forcer l'ouverture pour s'assurer de l'état du fichier est un peu infâme je trouve, parce que
- les exceptions c'est super lourd à créer et pas naturel comme façon de coder.
- ton test ne te préserve absolument pas de la possibilité qu'une appli verrouille le fichier dans le pouillème de seconde d'intervalle entre le return et ton traitement proprement dit.

 

edit : ceci étant dit je reconnais que je n'apporte pas de solution...

Message cité 1 fois
Message édité par TotalRecall le 26-04-2009 à 12:06:22

---------------
Topic .Net - C# @ Prog
Reply

Marsh Posté le 26-04-2009 à 12:22:15    

TotalRecall a écrit :

La technique qui consiste à forcer l'ouverture pour s'assurer de l'état du fichier est un peu infâme je trouve, parce que  
- les exceptions c'est super lourd à créer et pas naturel comme façon de coder.
- ton test ne te préserve absolument pas de la possibilité qu'une appli verrouille le fichier dans le pouillème de seconde d'intervalle entre le return et ton traitement proprement dit.
 
edit : ceci étant dit je reconnais que je n'apporte pas de solution...


Je sais, mais visiblement c'est la seule que j'ai trouvée, et personne ne fait autrement visiblement.  
 
Et dans mon cas personne ne peut revérouiller le fichier pour écrire dessus après qu'il me soit disponible.  
M'enfin si y a une meilleure solution je reste preneur, mais perso j'en ai pas d'autre.


---------------
"C'est vrai qu'un type aussi pénible de jour on serait en droit d'espérer qu'il fasse un break de nuit mais bon …"
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed