2009-06-28 5 views
4

Kennt jemand eine schnellere Möglichkeit, durch ein Verzeichnis und Unterordner aufzuzählen, um alle Dateien in der Aufzählung zu sammeln? Dies ist, was ich gerade habe:Schnelle Möglichkeit zum Auflisten aller Dateien einschließlich Unterordner

Public Shared allFiles() As String 
allFiles = Directory.GetFiles(<ServerLocation>, "*.*", SearchOption.AllDirectories) 

Vielen Dank! JFV

EDIT: Ich zähle diese Dateien von einem Serverstandort. Ich weiß nicht, ob das die Perspektive dieser Frage verändern wird oder nicht. Danke für alle bisherigen Eingaben!

Antwort

4

Kurze Antwort:

Wenn dieser Code funktionell richtig für Ihr Projekt ist, und Sie haben nicht bewiesen, es ist ein Problem mit einem Profiler sein dann es nicht ändern. Verwenden Sie weiterhin eine funktional korrekte Lösung, bis Sie nachweisen, dass sie langsam ist.

Lange Antwort:

Wie schnell oder dieses bestimmte Stück Code verlangsamen, hängt von einer Menge ist von Faktoren ab. Viele davon hängen von der spezifischen Maschine ab, auf der Sie laufen (zum Beispiel Geschwindigkeit der Festplatte). Wenn man sich Code anschaut, der das Dateisystem und nichts anderes betrifft, ist es sehr schwierig, "x ist schneller als y" mit einem gewissen Grad an Sicherheit zu sagen.

In diesem Fall kann ich nur eine Sache wirklich kommentieren. Der Rückgabetyp dieser Methode ist ein Array von FileInfo-Werten. Arrays erfordern zusammenhängenden Speicher und sehr große Arrays können Fragmentierungsprobleme in Ihrem Heap verursachen. Wenn Sie extrem große Verzeichnisse haben, die Sie lesen, könnte dies zu Heapfragmentierung und indirekt zu Leistungsproblemen führen.

Wenn sich herausstellt, dass es sich um ein Problem handelt, können Sie PInvoke in FindFirstFile/FindNextFile starten und nacheinander abrufen. Das Ergebnis wird wahrscheinlich langsamer in den CPU-Zyklen sein, aber weniger Speicherdruck haben.

Aber ich muss betonen, dass Sie diese Probleme vor Ihnen beheben müssen sie beweisen.

+0

+1 Viel besser ausgedrückt als ich konnte –

+0

Doch zur gleichen Zeit, jeder, der in einem großen Verzeichnis alle Dateien auflisten mit .NET weiß versucht hat, dass es sich um eine Leistung Problem. Listing 1000 Ordner Namen, nur die Ordnernamen, kann fast eine ganze Sekunde dauern. –

0

Dies ist eine grobe Art, es zu tun.

dir /s /b 

die Ausgabe dieses in eine Textdatei holen, es & Spaltung von \r\n lesen.
Führen Sie den obigen Befehl in einem bestimmten Verzeichnis aus, um zu sehen, ob es hilft.

nur auf die Verzeichnisse

dir /s /b /ad 

Um nur die

dir /s /b /a-d 

EDIT

Dateien erhalten zu erhalten: Jared ist recht, nicht andere Ansätze zu verwenden, es sei denn, Ihr Ansatz langsam bewiesen.

+1

Könnten Sie bitte klären, warum Sie den Aufruf von dir und das Lesen der Ausgabe für schneller halten als einen Aufruf von Directory.GetFiles? – Marek

3

mit System.Collections.Generic;

private static List<string> GetFilesRecursive(string b) 
{ 

      // 1. 
      // Store results in the file results list. 
      List<string> result = new List<string>(); 

      // 2. 
      // Store a stack of our directories. 
      Stack<string> stack = new Stack<string>(); 

      // 3. 
      // Add initial directory. 
      stack.Push(b); 

      // 4. 
      // Continue while there are directories to process 
      while (stack.Count > 0) 
      { 
       // A. 
       // Get top directory 
       string dir = stack.Pop(); 

       try 
       { 
        // B 
        // Add all files at this directory to the result List. 
        result.AddRange(Directory.GetFiles(dir, "*.*")); 

        // C 
        // Add all directories at this directory. 
        foreach (string dn in Directory.GetDirectories(dir)) 
        { 
         stack.Push(dn); 
        } 
       } 
       catch 
       { 
        // D 
        // Could not open the directory 
       } 
      } 
      return result; 
     } 

Props zum Original-Artikel: http://www.codeproject.com/KB/cs/workerthread.aspx

0

Heres meine Lösung.Der erste Start ist ein wenig langsam, ich arbeite daran. Das my.computer.filesystem-Objekt ist wahrscheinlich das Problem für den langsamen Start. Aber diese Methode listet 31.000 Dateien in weniger als 5 Minuten über ein Netzwerk auf.

Imports System.Threading 

Public Class ThreadWork 

Public Shared Sub DoWork() 
    Dim i As Integer = 1 
    For Each File As String In My.Computer.FileSystem.GetFiles("\\172.16.1.66\usr2\syscon\S4_650\production\base_prog", FileIO.SearchOption.SearchTopLevelOnly, "*.S4") 
     Console.WriteLine(i & ". " & File) 
     i += 1 
    Next 
End Sub 'DoWork 
End Class 'ThreadWork 

Module Module1 

Sub Main() 
    Dim myThreadDelegate As New ThreadStart(AddressOf ThreadWork.DoWork) 
    Dim myThread As New Thread(myThreadDelegate) 
    myThread.Start() 
    '"Pause" the console to read the data. 
    Console.ReadLine() 
End Sub 'Main 

End Module