2009-03-27 9 views
9

Ich habe eine Anwendung, wo ich manchmal aus der Datei lesen muss, in die geschrieben wird und als Ergebnis gesperrt wird. Wie ich von anderen questions verstanden habe, sollte ich die IOException abfangen und wiederholen, bis ich lesen kann.Wie man am besten auf die Freigabe eines Filelock wartet

Aber meine Frage ist, wie kann ich sicher wissen, dass die Datei gesperrt ist und dass es nicht ein anderes IOExcetpion auftritt.

Antwort

5

Wenn Sie eine Datei zum Einlesen öffnen.NET es irgendwann versuchen, eine Datei-Handelte mit der CreateFile API-Funktion zu erstellen, die die error code setzen die verwendet werden können, um zu sehen, warum es fehlgeschlagen:

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

Leider können Sie nicht sicher sein, dass der Win32-Fehler tatsächlich durch den Aufruf der CreateFile-API verursacht wurde. Dies könnte sich in einer anderen Version des Frameworks ändern. Um sicher zu sein, rufen Sie die Win32-API selbst auf. –

0

Daten zu lesen, die Sie tun können:

mit (Filestream fs = new Filestream (filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) {.. ..}

und in der Datei zu speichern:

mit (Filestream fs = new Datei Stream (Dateiname, FileMode.Append, FileAccess.Write, FileShare.Read | FileShare.Delete)) {...}

Flaggen am Ende des Konstrukteurs beschreibt, was andere Verfahren mit der Datei tun können. Es ist in Ordnung, natürlich, wenn Sie beide Schreib steuern und lesen ...

0

Sie gegen den Typ IOException vergleichen zu überprüfen und sehen, ob es sonst nicht etwas

Wie

if (ex is FileNotFoundException) 
ist

Sie können die Hilfe zu System.IO nachschlagen. Viele der Ausnahmen in dieser Klasse erben von IOException. Außerhalb der Überprüfung, ob es eine andere Art von Ausnahme ist, müssen Sie möglicherweise in der Nachricht der Beschreibung suchen, oder Sie können in Win32-API-Aufruf in Shell32.dll suchen. Möglicherweise befindet sich dort eine Funktion, um zu prüfen, ob eine Datei gesperrt ist.

Wenn Sie unbedingt warten müssen, können Sie Schleife verwenden, aber wenn Sie während des Wartens andere Aktionen ausführen möchten, verwenden Sie einen asynchronen Thread.

0

Haben Sie meinen Sie beide Lesen und Schreiben in die Datei? Oder dass eine externe Anwendung darauf schreibt.

Wenn Sie das Lesen und Schreiben tun, dann nehme ich an, Sie tun es auf verschiedenen Threads in diesem Fall werfen Sie einen Blick auf die ReaderWriteLock-Klasse, die das Management für Sie tun, und ermöglichen Ihnen, Zeitüberschreitungen bereitzustellen.

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

Ansonsten alles, was Sie tun müssen, ist Öffnen Sie die Datei in einem Nur-Lese-Modus. Dann sollten Sie keine Probleme haben:

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

Es gibt eine nützliche Diskussion über google groups, die Sie wirklich lesen sollen. Eine der Optionen ist in der Nähe von Darins; Um jedoch sicherzustellen, dass Sie den richtigen Win32-Fehler erhalten, sollten Sie die Win32 OpenFile() API selbst aufrufen (andernfalls wissen Sie wirklich nicht, welchen Fehler Sie abrufen).

Eine weitere Möglichkeit besteht darin, die Fehlermeldung zu analysieren: Dies wird fehlschlagen, wenn Ihre Anwendung in einer anderen Sprachversion ausgeführt wird.

Eine dritte Option besteht darin, innerhalb der Ausnahmeklasse mit Reflexion zu hacken, um das tatsächliche HRESULT herauszufischen.

Keine der Alternativen ist wirklich so attraktiv: Die IOException-Hierarchie würde von einigen IMHO-Unterklassen profitieren.