Grundsätzlich möchte ich prüfen, ob ich zum Öffnen der Datei berechtigt bin, bevor ich tatsächlich versuche, sie zu öffnen. Ich möchte für diese Prüfung keinen Versuch / Fang verwenden, es sei denn, ich muss. Gibt es eine Dateizugriffseigenschaft, die ich vorher überprüfen kann?
c#
.net
file-access
Horas
quelle
quelle
Antworten:
Ich habe dies in der Vergangenheit unzählige Male getan, und fast jedes Mal, wenn ich es getan habe, war ich falsch, den Versuch überhaupt zu machen.
Dateiberechtigungen (auch das Vorhandensein von Dateien) sind flüchtig - sie können sich jederzeit ändern. Dank des Murphy-Gesetzes umfasst dies insbesondere die kurze Zeit zwischen dem Überprüfen der Datei und dem Versuch, sie zu öffnen. Eine Änderung ist noch wahrscheinlicher, wenn Sie sich in einem Bereich befinden, in dem Sie wissen, dass Sie dies zuerst überprüfen müssen. Seltsamerweise wird es jedoch niemals in Ihren Test- oder Entwicklungsumgebungen passieren, die dazu neigen, ziemlich statisch zu sein. Dies macht es schwierig, das Problem später aufzuspüren, und macht es für diese Art von Fehler einfach, es in die Produktion zu bringen.
Dies bedeutet, dass Sie die Ausnahme trotz Ihrer Überprüfung immer noch behandeln müssen, wenn die Dateiberechtigungen oder das Vorhandensein schlecht sind. Ausnahmebehandlungscode ist erforderlich , unabhängig davon, ob Sie im Voraus nach den Berechtigungen der Datei suchen oder nicht. Der Ausnahmebehandlungscode bietet alle Funktionen der Existenz- oder Berechtigungsprüfung. Obwohl solche Ausnahmebehandlungsroutinen als langsam bekannt sind, ist es wichtig zu beachten, dass die Festplatten- E / A noch langsamer ist ... viel langsamer ... und das Aufrufen der Funktion .Exists () oder das Überprüfen von Berechtigungen eine zusätzliche Auslösung erzwingen aus dem Dateisystem.
Zusammenfassend ist eine erste Überprüfung vor dem Versuch, die Datei zu öffnen, sowohl redundant als auch verschwenderisch. Es gibt keinen zusätzlichen Vorteil gegenüber der Ausnahmebehandlung, es wird Ihre Leistung tatsächlich beeinträchtigen, nicht helfen, es erhöht die Kosten in Bezug auf mehr Code, der gewartet werden muss, und es kann subtile Fehler in Ihren Code einbringen. Es gibt überhaupt keinen Vorteil bei der ersten Überprüfung. Stattdessen sollten Sie hier nur versuchen, die Datei zu öffnen und Ihre Bemühungen in einen guten Ausnahmebehandler zu investieren, wenn dies fehlschlägt. Das Gleiche gilt auch dann, wenn Sie nur prüfen, ob die Datei vorhanden ist oder nicht. Diese Argumentation gilt für jede flüchtige Ressource.
quelle
Schneller Tipp für alle anderen, die mit einem ähnlichen Problem hierher kommen:
Achten Sie auf Web-Synchronisierungs-Apps wie DropBox. Ich habe gerade 2 Stunden damit verbracht zu denken, dass die "using" -Anweisung (Dispose pattern) in .NET fehlerhaft ist.
Schließlich wurde mir klar, dass Dropbox ständig Dateien im Hintergrund liest und schreibt, um sie zu synchronisieren.
Ratet mal, wo sich mein Visual Studio Projects-Ordner befindet? Natürlich im Ordner "My Dropbox".
Während ich meine Anwendung im Debug-Modus ausführte, wurde daher auch von DropBox kontinuierlich auf die Dateien zugegriffen, die sie las und schrieb, um sie mit dem DropBox-Server zu synchronisieren. Dies verursachte die Sperr- / Zugriffskonflikte.
Zumindest weiß ich jetzt, dass ich eine robustere Funktion zum Öffnen von Dateien benötige (dh TryOpen (), die mehrere Versuche unternimmt). Ich bin überrascht, dass es nicht bereits ein integrierter Bestandteil des Frameworks ist.
[Aktualisieren]
Hier ist meine Hilfsfunktion:
quelle
using
, muss der vom Anrufer verwendet werden ...using
wird hier nicht funktionieren. Am Ende des Verwendungsblocksfs
wird das Schließen erzwungen. Sie geben dem Anrufer einen GESCHLOSSENEN (so nutzlosen) Dateistream!Hier ist die Lösung, die Sie suchen
Dadurch wird eine neue Leseberechtigung basierend auf der Ansicht für den Pfad aller Dateien erstellt und anschließend überprüft, ob sie dem Lesezugriff auf Dateien entspricht.
quelle
Zuerst, was Joel Coehoorn gesagt hat.
Außerdem: Sie sollten die Annahmen untersuchen, die Ihrem Wunsch zugrunde liegen, die Verwendung von try / catch zu vermeiden, es sei denn, Sie müssen. Der typische Grund für die Vermeidung von Logik, die von Ausnahmen abhängt (das Erstellen von
Exception
Objekten funktioniert schlecht), ist wahrscheinlich nicht relevant für Code, der eine Datei öffnet.Ich nehme an, wenn Sie eine Methode schreiben, die a
List<FileStream>
durch Öffnen jeder Datei in einem Verzeichnis-Teilbaum auffüllt, und Sie erwartet haben, dass auf eine große Anzahl von Dateien nicht zugegriffen werden kann, sollten Sie die Dateiberechtigungen überprüfen, bevor Sie versuchen, eine Datei zu öffnen, damit Sie dies nicht tun bekomme zu viele Ausnahmen. Aber Sie würden die Ausnahme trotzdem behandeln. Außerdem stimmt wahrscheinlich etwas furchtbar nicht mit dem Design Ihres Programms, wenn Sie eine Methode schreiben, die dies tut.quelle
quelle
quelle
attempts
von ref übergeben? Das macht keinen Sinn. Auch nicht testen<=
statt nur==
.throw ex
tatsächlich das Richtige ist .