Die oben akzeptierten Antworten weisen ein Problem auf, bei dem der Code nicht funktioniert, wenn die Datei zum Schreiben mit einem FileShare.Read-Modus geöffnet wurde oder wenn die Datei ein Read-Only-Attribut hat. Diese modifizierte Lösung funktioniert am zuverlässigsten, wobei zwei Dinge zu beachten sind (die auch für die akzeptierte Lösung gelten):
- Es funktioniert nicht für Dateien, die mit einem Schreibfreigabemodus geöffnet wurden
- Dabei werden Threading-Probleme nicht berücksichtigt, so dass Sie es sperren oder Threading-Probleme separat behandeln müssen.
Unter Berücksichtigung der obigen Ausführungen wird geprüft, ob die Datei entweder zum Schreiben gesperrt o gesperrt, um das Lesen zu verhindern :
public static bool FileLocked(string FileName)
{
FileStream fs = null;
try
{
// NOTE: This doesn't handle situations where file is opened for writing by another process but put into write shared mode, it will not throw an exception and won't show it as write locked
fs = File.Open(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None); // If we can't open file for reading and writing then it's locked by another process for writing
}
catch (UnauthorizedAccessException) // https://msdn.microsoft.com/en-us/library/y973b725(v=vs.110).aspx
{
// This is because the file is Read-Only and we tried to open in ReadWrite mode, now try to open in Read only mode
try
{
fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (Exception)
{
return true; // This file has been locked, we can't even open it to read
}
}
catch (Exception)
{
return true; // This file has been locked
}
finally
{
if (fs != null)
fs.Close();
}
return false;
}
35 Stimmen
Sie können dies testen, indem Sie alle offenen Handles auf dem System untersuchen. Da es sich bei Windows jedoch um ein Multitasking-Betriebssystem handelt, besteht die Möglichkeit, dass direkt nach der Ausführung des Codes, mit dem festgestellt werden soll, ob die Datei geöffnet ist, ein Prozesscode mit der Verwendung dieser Datei beginnt und zu dem Zeitpunkt, zu dem Sie versuchen, sie zu verwenden, ein Fehler auftritt. Es ist jedoch nicht verkehrt, zuerst zu prüfen, ob die Datei geöffnet ist; gehen Sie nur nicht davon aus, dass sie nicht verwendet wird, wenn Sie sie tatsächlich benötigen.
6 Stimmen
Aber gerade für dieses spezielle Problem würde ich empfehlen, die Dateihandles nicht zu untersuchen und nur eine bestimmte Anzahl von Versuchen durchzuführen, z. B. 3-5, bevor sie fehlschlagen.
0 Stimmen
Wie wird diese Bilddatei erstellt? Können Sie Ihr Programm anhalten/schlafen/pausieren, bis die Erzeugung abgeschlossen ist? Das ist bei weitem der bessere Weg, um die Situation zu bewältigen. Wenn nicht, dann glaube ich nicht, dass Sie eine Ausnahmebehandlung vermeiden können.
0 Stimmen
Ist nicht jede Verwendung von Ausnahmen eine Überprüfung einer Annahme, indem man etwas potenziell Gefährliches tut und dabei absichtlich die Möglichkeit eines Fehlschlags nicht ausschließt?
40 Stimmen
Ihre Philosophie hat ein schlechtes Verständnis von Ausnahmen. Die meisten Leute denken, Ausnahmen bedeuten heilige Scheiße-aus-dem-Doom-irgendetwas-ist-falsch-die-die-die. Wenn Ausnahme bedeutet.... Ausnahme. Es bedeutet, dass etwas Außergewöhnliches passiert ist, das Sie "behandeln" (oder berücksichtigen) müssen. Vielleicht wollen Sie den Datenzugriff immer wieder versuchen, vielleicht muss der Benutzer wissen, dass Sie keine Verbindung herstellen können. Was tun Sie dann? Sie behandeln die ConnectionFailedException und benachrichtigen den Benutzer, so dass er vielleicht nach einer Stunde aufhört, es zu versuchen, und bemerkt, dass das Kabel ausgesteckt ist.
0 Stimmen
Warum die Prüfung und Verarbeitung in verschiedenen Prozeduren? try {open file in FileShare.None; process file; close file} catch {filelocked) {///locked, we'll get it next time}
2 Stimmen
Lee Louviere hat eine berechtigte Abneigung dagegen, mit Ausnahmen zu arbeiten. Wenn man mit der filexists-Methode leicht herausfinden kann, ob eine Datei existiert, gibt es dann einen ähnlichen Befehl, um herauszufinden, ob die Datei, mit der man arbeiten möchte, in Gebrauch ist? Ich glaube, das ist die eigentliche Frage, die der Benutzer stellt.
1 Stimmen
@webs Manche Ausnahmen sind einfach eine Tatsache. Die Verwendung von File.Exists() ist gut, aber wie die Antwort sagt, ist es nicht immer möglich, sie zu vermeiden. Zum Beispiel könnte eine Datei zwischen dem Zeitpunkt, an dem Sie prüfen, ob sie existiert, und dem Zeitpunkt, an dem Sie sie tatsächlich öffnen, existieren. Diese unbestimmte Zeitspanne ist in den meisten Fällen gut genug, aber es gibt keine Garantien und daher sollte ein Exception-Handler den Aufruf zum Öffnen der Datei einschließen usw.
1 Stimmen
@webs Wenn Sie leicht filexists Methode verwenden können, um zu wissen, ob eine Datei vorhanden ist, was ähnlichen Befehl vorhanden ist, um zu wissen, ob die Datei, die Sie mit arbeiten möchten, in Gebrauch ist? Ich bin etwas spät dran, aber diese beiden Beispiele sind TOCTOU-Wanzen . Die Ergebnisse sind sofort ungültig. "Check-then-do" ist nutzlos - der "Check" kann nicht mit dem "Do" identisch sein, so dass der "Check" aus unterschiedlichen Gründen fehlschlagen oder erfolgreich sein kann, wenn der "Do" fehlschlagen würde. Wenn Sie eine Datei öffnen müssen DATEI ÖFFNEN . Nichts anderes kann Ihnen einen endgültigen Beweis dafür liefern, dass die Öffnung funktionieren wird.
2 Stimmen
Was ist, wenn ich nicht herausfinden möchte, ob ich überhaupt in eine Datei schreiben KANN, sondern ob ich lieber nicht schreiben sollte, obwohl ich es könnte, weil jemand anderes gerade an derselben Datei arbeitet?