C # – Ruft eine Liste der Dateien ab, mit Ausnahme der versteckten Dateien

Directory.GetFiles() gibt alle Dateien zurück, auch diejenigen, die als ausgeblendet markiert sind. Gibt es eine Möglichkeit, eine Liste von Dateien zu erhalten, die versteckte Dateien ausschließt?

   

Dies sollte für Sie funktionieren:

 DirectoryInfo directory = new DirectoryInfo(@"C:\temp"); FileInfo[] files = directory.GetFiles(); var filtered = files.Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden)); foreach (var f in filtered) { Debug.WriteLine(f); } 
 // check whether a file is hidden bool isHidden = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden); 

Mit .NET 4.0 und Directory.EnumerateDirectories können Sie dieses Konstrukt verwenden:

 var hiddenFilesQuery = from file in Directory.EnumerateDirectories(@"c:\temp") let info = new FileInfo(file) where (info.Attributes & FileAttributes.Hidden) == 0 select file; 

Dies ist im Grunde die gleiche wie die andere Antwort, außer Directory.EnumerateDirectories ist ein bisschen fauler. Dies ist jedoch nicht sehr nützlich, wenn Sie alles aufzählen.

(Das Let ist hier, um die Abfrage ein, aber mehr readable).

wenn Verwendung verwenden:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == 0);

Dies findet nur keine versteckte Datei, so dass Sie verwenden können:

var filtered = files.Select(f => f) .Where(f => (f.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden);

Dies dient nur dazu, die versteckte Datei zu lesen

Eine Zeile Code:

 FileInfo[] tmpFiles = tempDir.GetFiles().Where(file => (file.Attributes & FileAttributes.Hidden) == 0).ToArray(); 

Wenn Sie SearchOption.TopDirectoryOnly verwenden, ist es relativ einfach. Es wird jedoch viel komplexer, wenn Sie alle Dateien rekursiv mit SearchOption.AllDirectories auflisten möchten. Wenn Sie GetFiles und dann filtern können, lesen Sie nur, aber leider funktioniert es nicht mit Verzeichnissen, die als versteckt markiert sind. Dateien unter diesen Ordnern werden ebenfalls aufgelistet, aber sie sind im Gegensatz zum Verzeichnis nicht versteckt.

Sie können auch GetDirectories verwenden, aber wiederum – Sie können nicht alles rekursiv mit SearchOption.AllDirectories auflisten, da es auch Ordner auflistet, die sich unter versteckten Ordnern befinden, aber diese Ordner haben kein verstecktes Attribut aktiviert.

Dies ist zumindest für den versteckten Ordner Tortoise svn .svn der Fall. Es enthält viele Ordner, die nicht versteckt sind, aber .svn ist versteckt. Endlich habe ich eine function geschrieben, die so aussieht:

  SearchOption sopt = SearchOption.AllDirectories; List listFiles = new List(); List dirs2scan = new List(); dirs2scan.Add(new DirectoryInfo(fromPath) ); for( ; dirs2scan.Count != 0; ) { int scanIndex = dirs2scan.Count - 1; // Try to preserve somehow alphabetic order which GetFiles returns // by scanning though last directory. FileInfo[] filesInfo = dirs2scan[scanIndex].GetFiles(pattern, SearchOption.TopDirectoryOnly); foreach (FileInfo fi in filesInfo) { if (bNoHidden && fi.Attributes.HasFlag(FileAttributes.Hidden)) continue; listFiles.Add(fi.FullName); } if( sopt != SearchOption.AllDirectories ) break; foreach (DirectoryInfo dir in dirs2scan[scanIndex].GetDirectories("*", SearchOption.TopDirectoryOnly)) { if (bNoHidden && dir.Attributes.HasFlag(FileAttributes.Hidden)) continue; dirs2scan.Add(dir); } dirs2scan.RemoveAt(scanIndex); } 

sopt kann bei Bedarf als Parameter in der function verwendet oder bei Bedarf entfernt werden.

Eigentlich möchte ich lieber einen functionsparameter an eine Methode übergeben, die das tut, was ich will. Ich habe eine SearchDirectory-Methode, die die Grundlage für die meisten Aufrufe ist, die ich verwende:

 private void SearchDirectory(DirectoryInfo startDirectory, string pattern, Action act) { foreach (var file in startDirectory.GetFiles(pattern)) act(file); foreach (var directory in startDirectory.GetDirectories()) SearchDirectory(directory, pattern, act); } private List SearchDirectory(DirectoryInfo startDirectory, string pattern, Func isWanted) { var lst = new List(); SearchDirectory(startDirectory, pattern, (fi) => { if (isWanted(fi)) lst.Add(fi); }); return lst; } 

Dann können Sie die anderen aufgelisteten Lösungen verwenden, um eine IsHidden-function zu schreiben, die eine einzelne FileInfo verwendet und wenn ja true zurückgibt:

 private bool IsHiddenDirectory(DirectoryInfo d) { if (d == null) return false; if (d.Attributes.HasFlag(FileAttributes.Hidden))) return true; if (d.Parent == null) return false; return IsHiddenDirectory(d.Parent); } private bool IsHidden(FileInfo fi) { if ((fi.Attributes & FileAttributes.Hidden) != 0) return true; // If you're worried about parent directories hidden: return IsHiddenDirectory(fi.Directory); // otherwise: return false; } 

Dann kann ich es ganz einfach in einer anderen Methode nennen:

 var files = SearchDirectory(new DirectoryInfo("C:\temp\"), "*.xml", (fi) => { return !IsHidden(fi); ); 
 static bool IsHidden(string p) { return p.Contains("Hidden"); } DirectoryInfo directory = new DirectoryInfo(@"C:\temp"); FileInfo[] files = directory.GetFiles(); var filtered = files.Where(f => !IsHidden(File.GetAttributes(f).ToString())); foreach (var f in filtered) { Debug.WriteLine(f); } 

Schritte:

  1. Erstellen Sie bool, das true zurückgibt, wenn die Zeichenfolge ‘Versteckt’ enthält —- static bool IsHidden(string p){return p.Contains("Hidden");}

  2. Verzeichnisinfo abrufen —- DirectoryInfo directory = new DirectoryInfo(@"C:\temp");

  3. Datei-Info-Array aus dem Verzeichnis FileInfo[] files = directory.GetFiles(); —- FileInfo[] files = directory.GetFiles();

  4. hole Datei info Attribute und konvertiere in eine Zeichenkette aus Datei Info Array und überprüfe, ob sie ‘Versteckt’ enthält oder nicht —- var filtered = files.Where(f=>!IsHidden(File.GetAttributes(f).ToString()));