2009-03-27 12 views
9

J'ai une application où j'ai parfois besoin de lire à partir du fichier en train d'être écrit et par conséquent verrouillé. Comme je l'ai compris d'autres questions je devrais attraper le IOException et réessayer jusqu'à ce que je puisse lire.comment attendre au mieux qu'un filelock se libère

Mais ma question est comment puis-je savoir avec certitude que le fichier est verrouillé et que ce n'est pas une autre IOExcetpion qui se produit.

Répondre

5

Lorsque vous ouvrez un fichier à lire.NET il à un moment essayer de créer un descripteur de fichier en utilisant la fonction API CreateFile qui définit la error code qui peut être utilisé pour voir pourquoi il a échoué:

const int ERROR_SHARING_VIOLATION = 32; 
try 
{ 
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
    } 
} 
catch (IOException ex) 
{ 
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION) 
    { 
     Console.WriteLine("The process cannot access the file because it is being used by another process."); 
    } 
} 
+2

Malheureusement, vous ne pouvez pas être certain que l'erreur Win32 a été réellement provoquée par l'appel API CreateFile. Cela pourrait changer dans une autre version du framework. Pour être certain, appelez l'API Win32 vous-même. –

0

Pour lire les données que vous pouvez faire:

utilisant (FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) {.. ..}

et d'enregistrer dans le fichier:

utilisant (FileStream = new fichier Stream (nomFichier, FileMode.Append, FileAccess.Write, FileShare.Read | FileShare.Delete)) {...}

Drapeaux à la fin des constructeurs décrit ce que d'autres processus peut faire avec le fichier. Il est très bien, bien sûr, si vous contrôlez à la fois écriture et de lecture ...

0

Vous pouvez comparer par rapport au type IOException pour vérifier et voir si ce n'est pas autre chose

Tels que

if (ex is FileNotFoundException) 

Vous pouvez rechercher l'aide sur System.IO. Un grand nombre d'exceptions dans cette classe héritent de IOException. En dehors de la vérification pour voir si c'est un autre type d'exception, vous devrez peut-être regarder dans le message de la description ou vous pourriez envisager de faire un appel API Win32 dans shell32.dll. Il peut y avoir une fonction pour vérifier si un fichier est verrouillé.

De même, si vous devez absolument attendre, vous pouvez utiliser la boucle, mais si vous voulez effectuer d'autres actions en attendant, utilisez un thread asynchrone.

0

Voulez-vous dire que vous êtes à la fois la lecture et l'écriture dans le fichier? Ou qu'une application externe lui écrit. Si vous faites la lecture et l'écriture, alors je suppose que vous le faites sur différents threads, auquel cas jetez un oeil à la classe ReaderWriteLock qui fera cela la gestion pour vous, et vous permettre de fournir des délais d'attente.

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

Sinon, tout ce que vous devez faire est d'ouvrir le fichier dans un mode lecture seule. Ensuite, vous ne devriez pas avoir de problèmes:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)); 
4

Il y a une discussion utile sur google groups que vous devriez vraiment lire. Une des options est proche de celle de darin; Cependant, pour vous assurer d'obtenir la bonne erreur win32, vous devriez appeler vous-même l'API Win32 OpenFile() (sinon, vous ne savez vraiment pas quelle erreur vous récupérez).

Une autre consiste à analyser le message d'erreur: celui-ci échouera si votre application est exécutée sur une autre version linguistique.

Une troisième option consiste à pirater à l'intérieur de la classe d'exception avec réflexion pour pêcher le HRESULT réel. Aucune des alternatives n'est vraiment attrayante: la hiérarchie IOException bénéficierait de quelques sous-classes supplémentaires IMHO.