20 Stimmen

Suche nach der Anzahl der Dateien mit einer bestimmten Erweiterung in allen Unterverzeichnissen

Gibt es eine Möglichkeit, die Anzahl der Dateien eines bestimmten Typs zu finden, ohne eine Schleife durch alle Ergebnisse in einem Directory.GetFiles() oder einer ähnlichen Methode? Ich suche so etwas wie dies:

int ComponentCount = MagicFindFileCount(@"c:\windows\system32", "*.dll");

Ich weiß, dass ich eine rekursive Funktion machen kann, um Directory.GetFiles aufzurufen, aber es wäre viel sauberer, wenn ich dies ohne die ganze Iteration tun könnte.

EDIT : Wenn es nicht möglich ist, dies zu tun, ohne selbst zu rekursieren und zu iterieren, was wäre dann der beste Weg, dies zu tun?

37voto

Jon Limjap Punkte 92084

Sie sollten die Verzeichnis.GetFiles(Pfad, searchPattern, SearchOption) Überladung von Directory.GetFiles().

Path gibt den Pfad an, searchPattern spezifiziert Ihre Wildcards (z.B. *, *.format) und SearchOption bietet die Möglichkeit, Unterverzeichnisse einzuschließen.

Die Length-Eigenschaft des Rückgabe-Arrays dieser Suche liefert die richtige Dateizahl für Ihr spezielles Suchmuster und Ihre Option:

string[] files = directory.GetFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories);

return files.Length;

EDIT : Alternativ können Sie auch Directory.EnumerateFiles-Methode

return Directory.EnumerateFiles(@"c:\windows\system32", "*.dll", SearchOption.AllDirectories).Count();

0 Stimmen

Dies führt zu massiven Leistungsproblemen bei einer großen Anzahl von Dateien.

0 Stimmen

@Aim - Können Sie (oder jemand anderes) Ihre Aussage bitte quantifizieren? Wie langsam ist ein "massives Leistungsproblem"? Wie groß ist die Anzahl der Dateien? Die Jon-Lösung funktioniert bei mir, aber ich würde gerne wissen, wann/wie sie problematisch werden könnte.

6 Stimmen

@DavidHAust Der Grund dafür ist, dass GetFiles Methode werden die gesamte Liste der Dateien, die sich in einem Verzeichnis befinden. Die bevorzugte Methode zum Aufruf ist jetzt Directory.EnumerateFiles da es die Dateien zurückstreamt (über eine yield -ähnlichen Mechanismus), da der zugrunde liegende Aufruf an das Betriebssystem die Ergebnisse zurückliefert.

8voto

Dean Punkte 3256

Die eleganteste Methode wäre die Verwendung von linq:

var fileCount = (from file in Directory.EnumerateFiles(@"H:\iPod_Control\Music", "*.mp3", SearchOption.AllDirectories)
                    select file).Count();

6 Stimmen

Warum nicht Directory.EnumerateFiles(@"H:\iPod_Control\Music", "*.mp3", SearchOption.AllDirectories).Count()

7voto

jfs Punkte 16666

Sie können diese Überladung von GetFiles verwenden:

Directory.GetFiles Methode (String, String, SearchOption )

und dieses Mitglied von SearchOption:

AllDirectories - Beinhaltet das aktuelle Verzeichnis und alle Unterverzeichnisse in einen Suchvorgang ein. Diese Option schließt reparierte Punkte wie gemountete Laufwerke und symbolische Links in die Suche.

GetFiles gibt ein Array von Strings zurück, so dass Sie nur die Länge erhalten können, die die Anzahl der gefundenen Dateien ist.

6voto

Sauleil Punkte 2513

Ich war auf der Suche nach einer optimierten Version. Da ich sie nicht gefunden habe, habe ich beschlossen, sie zu codieren und hier zu teilen:

    public static int GetFileCount(string path, string searchPattern, SearchOption searchOption)
    {
        var fileCount = 0;
        var fileIter = Directory.EnumerateFiles(path, searchPattern, searchOption);
        foreach (var file in fileIter)
            fileCount++;
        return fileCount;
    }

Alle Lösungen, die GetFiles/GetDirectories verwenden, sind ziemlich langsam, da all diese Objekte erstellt werden müssen. Bei Verwendung der Aufzählung werden keine temporären Objekte (FileInfo/DirectoryInfo) erstellt.

siehe Bemerkungen http://msdn.microsoft.com/en-us/library/dd383571.aspx für weitere Informationen

1voto

Huppie Punkte 10951

Mit Rekursion würde Ihr MagicFindFileCount wie folgt aussehen:

private int MagicFindFileCount( string strDirectory, string strFilter ) {
     int nFiles = Directory.GetFiles( strDirectory, strFilter ).Length;

     foreach( String dir in Directory.GetDirectories( strDirectory ) ) {
        nFiles += GetNumberOfFiles(dir, strFilter);
     }

     return nFiles;
  }

Obwohl Jons Lösung könnte die bessere Lösung sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X