Benutzer mit den meisten Antworten
Bei EnumerateFiles Fehler UnauthorizedAccessException durch try/catch abfangen?

Frage
-
Hallo,
ich habe mal ein Verständnisfrage.
Ich lesen mit "var fnLst = Directory.EnumerateFiles(...)" große Verzeichnisse ein.
Im nachfolgenden "foreach(var fn in fnLst)" bekomme ich den Fehler: "UnauthorizedAccessException", weil fnLst eine Datei enthält auf die ich keine Zugriffrechte habe.Ich möchte aber nur Dateien einlesen für die der Nutzer eine Berechtigung hat.
Im Netz habe ich dafür viele ältere Lösungen gefunden. Aber alle fangen den Fehler mit try/catch ab. Ich habe mal gelernt, dass dies ein sehr schlechter Programmierstil ist, wenn man voraussehbares Verhalten mit der Fehlerbehandlung behandelt.
Gibt es zwischenzeitlich neuere Methoden oder Verfahren um dieses Problem zu lösen?Gruß Klaus
Antworten
-
Hallo Klaus,
im Falle des Auflisten von Dateien und Verzeichnissen geht es ohne die Behandlung von Ausnahmen nicht. Der Grund ist, dass die Basis das Windows (Unmanged) API ist - siehe z. B.: FindFile - und der von Windows ausgelöste Fehlercode in eine Ausnahme umgewandelt wird.
Im Falle einer Zugriffsverletzung eine UnauthorizedAccessException. Die möglichen Ausnahmen findest du in der API Dokumentation.
Will man die Ausnahme vermeiden, muss man entweder selbst über das unmanaged API gehen, siehe obiges Beispiel - oder mit erhöhten Rechten arbeiten, wobei letzteres allgemein eine schlechte Idee ist.
Aber i. a. sollte man mit der Ausnahme umgehen und Suchen auf konkrete Verzeichnisse beschränken, anstatt in einem Wurzelknoten wie C:\ anzufangen.Vermeiden sollte man wie SearchOption.AllDirectories, und anstatt dessen eine tiefere Hierarchie selbst traversieren, wenn es nötig ist.
Dann bleiben solche Ausnahmen auch die Ausnahme, und der Performance tut es gut, wenn nicht allzu viel durchlaufen werden muss.
Gruß Elmar- Als Antwort markiert Klaus Raabe Dienstag, 3. Juli 2018 15:52
-
Hallo Stefan,
Klaus Problem sind nicht Dateien mit ReadOnly Flag sondern fehlende Zugriffsrechte auf Ordner und/oder Dateien, was dann bei EnumerateFiles eben dazu führt, dass eine UnauthorizedAccessException ausgelöst wird.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Als Antwort markiert Klaus Raabe Dienstag, 3. Juli 2018 15:52
Alle Antworten
-
Hi,
bin mir jetzt nicht sicher, wo genau die Exception geworfen wird, aber du kannst das Datei-Attribut abfragen:
string filePath = @"C:\TestDir\readtest.txt"; FileAttributes attr = (new FileInfo(filePath)).Attributes; if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { Console.WriteLine("read-only."); }
Wobei ich nicht weiß, was an try-catch böse ist oder ob es einen Performance-Nachteil hat.
du kannst auch versuchen, den Schreibschutz zu entfernen:
File.SetAttributes(filePath, File.GetAttributes(filePath) & ~FileAttributes.ReadOnly);
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
- Bearbeitet Stefan Krömer Dienstag, 3. Juli 2018 11:11
-
Hallo Stefan,
Danke für die schnelle Antwort.
"bin mir jetzt nicht sicher, wo genau die Exception geworfen wird, aber du kannst das Datei-Attribut abfragen:"
Der Fehler wird schon bei "foreach" geworfen. Er springt nicht mal in die Schleife rein. Deshalb kann ich vor dem Zugriff nicht das Attributes prüfen.
"Wobei ich nicht weiß, was an try-catch böse ist oder ob es einen Performance-Nachteil hat."
Wenn ich vorhersehen kann welche Fehler auftreten könnten, sollte ich die durch entsprechenden Code vermeiden und nicht nach dem Auslösen behandeln. So war es zumindest unter Delphi üblich.
Wenn man das unter C# nicht so eng sieht, soll es mir Recht sein.
Ich werde mir dann mal die vielen Lösungen im Netz genauer ansehen und ausprobieren.
Gruß Klaus.
-
Hallo Klaus,
im Falle des Auflisten von Dateien und Verzeichnissen geht es ohne die Behandlung von Ausnahmen nicht. Der Grund ist, dass die Basis das Windows (Unmanged) API ist - siehe z. B.: FindFile - und der von Windows ausgelöste Fehlercode in eine Ausnahme umgewandelt wird.
Im Falle einer Zugriffsverletzung eine UnauthorizedAccessException. Die möglichen Ausnahmen findest du in der API Dokumentation.
Will man die Ausnahme vermeiden, muss man entweder selbst über das unmanaged API gehen, siehe obiges Beispiel - oder mit erhöhten Rechten arbeiten, wobei letzteres allgemein eine schlechte Idee ist.
Aber i. a. sollte man mit der Ausnahme umgehen und Suchen auf konkrete Verzeichnisse beschränken, anstatt in einem Wurzelknoten wie C:\ anzufangen.Vermeiden sollte man wie SearchOption.AllDirectories, und anstatt dessen eine tiefere Hierarchie selbst traversieren, wenn es nötig ist.
Dann bleiben solche Ausnahmen auch die Ausnahme, und der Performance tut es gut, wenn nicht allzu viel durchlaufen werden muss.
Gruß Elmar- Als Antwort markiert Klaus Raabe Dienstag, 3. Juli 2018 15:52
-
Hi,
was du machen könntest ist folgendes:
var list = Directory.EnumerateFiles(sourceDirectory, "*.txt", SearchOption.AllDirectories).Where(f => !new FileInfo(f).Attributes.HasFlag(FileAttributes.ReadOnly)); foreach (var currentFile in list) { var b = File.ReadAllText(currentFile);; }
Dadurch werden Dateien ausgelassen, welche das Read-only Attribut gesetzt haben.
Gruß
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP
- Bearbeitet Stefan Krömer Dienstag, 3. Juli 2018 12:59
-
Hallo Stefan,
Klaus Problem sind nicht Dateien mit ReadOnly Flag sondern fehlende Zugriffsrechte auf Ordner und/oder Dateien, was dann bei EnumerateFiles eben dazu führt, dass eine UnauthorizedAccessException ausgelöst wird.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport- Als Antwort markiert Klaus Raabe Dienstag, 3. Juli 2018 15:52
-
Hallo Stefan,
Klaus Problem sind nicht Dateien mit ReadOnly Flag sondern fehlende Zugriffsrechte auf Ordner und/oder Dateien, was dann bei EnumerateFiles eben dazu führt, dass eine UnauthorizedAccessException ausgelöst wird.
Freiberufler im Bereich Softwareentwicklung Von der PLC und Robotik zu VB.NET & C#, vorrangig WPF und UWP