Sortieren von Directory.GetFiles ()

System.IO.Directory.GetFiles() gibt eine string[] . Wie lautet die Standardsortierreihenfolge für die zurückgegebenen Werte? Ich nehme mit Namen an, aber wenn ja, wie stark beeinflusst die aktuelle Kultur das? Kannst du es zu etwas wie Erstellungsdatum ändern?

Update: MSDN weist darauf hin, dass die Sortierreihenfolge nicht für .Net 3.5 garantiert ist, aber die 2.0-Version der Seite sagt überhaupt nichts und keine der Seiten wird Ihnen helfen, nach Dingen wie Erstellungs- oder Änderungszeit zu sortieren. Diese Information ist verloren, sobald Sie das Array haben (es enthält nur Strings). Ich könnte einen Vergleicher erstellen, der nach jeder Datei sucht, die es bekommt, aber das bedeutet, dass man wiederholt auf das Dateisystem zugreift, wenn die Methode .GetFiles () dies bereits tut. Scheint sehr ineffizient.

   

Wenn Sie an Eigenschaften der Dateien wie CreationTime interessiert sind, wäre es sinnvoller, System.IO.DirectoryInfo.GetFileSystemInfos () zu verwenden. Sie können diese dann mit einer der Erweiterungsmethoden in System.Linq sortieren, zB:

 DirectoryInfo di = new DirectoryInfo("C:\\"); FileSystemInfo[] files = di.GetFileSystemInfos(); var orderedFiles = files.OrderBy(f => f.CreationTime); 

Bearbeiten – Entschuldigung, ich habe das .NET2-Tag nicht bemerkt, also ignoriere die LINQ-Sortierung. Der Vorschlag, System.IO.DirectoryInfo.GetFileSystemInfos () zu verwenden, gilt jedoch weiterhin.

In .NET 2.0 müssen Sie Array.Sort verwenden, um die FileSystemInfos zu sortieren.

Darüber hinaus können Sie einen Comparer-Delegat verwenden, um zu vermeiden, dass Sie eine class nur für den Vergleich deklarieren müssen:

 DirectoryInfo dir = new DirectoryInfo(path); FileSystemInfo[] files = dir.GetFileSystemInfos(); // sort them by creation time Array.Sort(files, delegate(FileSystemInfo a, FileSystemInfo b) { return a.LastWriteTime.CompareTo(b.LastWriteTime); }); 

Hier ist die VB.Net-Lösung, die ich verwendet habe.

Machen Sie zuerst eine class zum Vergleichen von Daten:

 Private Class DateComparer Implements System.Collections.IComparer Public Function Compare(ByVal info1 As Object, ByVal info2 As Object) As Integer Implements System.Collections.IComparer.Compare Dim FileInfo1 As System.IO.FileInfo = DirectCast(info1, System.IO.FileInfo) Dim FileInfo2 As System.IO.FileInfo = DirectCast(info2, System.IO.FileInfo) Dim Date1 As DateTime = FileInfo1.CreationTime Dim Date2 As DateTime = FileInfo2.CreationTime If Date1 > Date2 Then Return 1 If Date1 < Date2 Then Return -1 Return 0 End Function End Class 

Verwenden Sie dann den Vergleich, während Sie das Array sortieren:

 Dim DirectoryInfo As New System.IO.DirectoryInfo("C:\") Dim Files() As System.IO.FileInfo = DirectoryInfo.GetFiles() Dim comparer As IComparer = New DateComparer() Array.Sort(Files, comparer) 

 Dim Files() As String Files = System.IO.Directory.GetFiles("C:\") Array.Sort(Files) 

Von msdn :

Die Reihenfolge der zurückgegebenen Dateinamen ist nicht garantiert. Verwenden Sie die Sort () -Methode, wenn eine bestimmte Sortierreihenfolge erforderlich ist.

Die Sort () -Methode ist das Standard-Array.Sort (), das IComparables (neben anderen Überladungen) aufnimmt. Wenn Sie also nach dem Erstellungsdatum sortieren, wird die Lokalisierung basierend auf den Maschineneinstellungen durchgeführt.

Sie können benutzerdefinierte iComparer zum Sortieren implementieren. Lesen Sie die Dateiinformationen für Dateien und vergleichen Sie, wie Sie möchten.

 IComparer comparer = new YourCustomComparer(); Array.Sort(System.IO.Directory.GetFiles(), comparer); 

msdn info IComparer-Schnittstelle

Eine prägnantere VB.Net Version … ist sehr schön. Vielen Dank. Um die Liste in umgekehrter Reihenfolge zu durchlaufen, fügen Sie die umgekehrte Methode hinzu …

 For Each fi As IO.FileInfo In filePaths.reverse ' Do whatever you wish here Next 

Die MSDN-Dokumentation besagt, dass keine Garantie für eine Reihenfolge der Rückgabewerte besteht. Sie müssen die Sort () -Methode verwenden.

Sie haben Recht, der Standardwert ist mein Name asc. Der einzige Weg, den ich gefunden habe, um die Sortierreihenfolge zu ändern, um eine Datentabelle von der FileInfo-Sammlung zu erstellen.

Sie können dann die DefaultView aus der Datentabelle verwenden und das Verzeichnis mit der .Sort-Methode sortieren.

Dies ist ziemlich involvierend und ziemlich langsam, aber ich hoffe, dass jemand eine bessere Lösung veröffentlichen wird.

Sie könnten eine benutzerdefinierte IComparer-Schnittstelle schreiben, die nach dem Erstellungsdatum sortiert und dann an Array.Sort übergeben wird. Sie sollten sich wahrscheinlich auch StrCmpLogical ansehen, was für die Sortierung des Explorers verwendet wird (korrekte Sortierung von Zahlen mit Text).

Wenn Sie nach etwas wie Erstellungsdatum sortieren möchten, müssen Sie wahrscheinlich DirectoryInfo.GetFiles verwenden und dann das resultierende Array mit einem geeigneten Prädikat sortieren.

Nur eine Idee. Ich möchte einen einfachen Ausweg finden und versuchen, bereits verfügbare Ressourcen wieder zu verwenden. Wenn ich Dateien sortieren würde, hätte ich einfach einen process erstellt und syscal auf “DIR [x: \ Folders \ SubFolders *. *] / s / b / on” gesetzt und die Ausgabe erfasst.

Mit dem Befehl DIR des Systems können Sie sortieren nach:

 /O List by files in sorted order. sortorder N By name (alphabetic) S By size (smallest first) E By extension (alphabetic) D By date/time (oldest first) G Group directories first - Prefix to reverse order The /S switch includes sub folders 

Ich bin nicht sicher, ob D = nach Datum / Uhrzeit LastModifiedDate oder FileCreateDate verwendet. Aber wenn die benötigte Sortierreihenfolge bereits im DIR-Befehl eingebaut ist, werde ich das durch Aufruf von syscall bekommen. Und es ist SCHNELL. Ich bin nur der Faule;)

Nach ein wenig googeln habe ich gefunden um nach Datum / Uhrzeit zu sortieren: –

 /t [[:]TimeField] : Specifies which time field to display or use for sorting. The following list describes each of the values you can use for TimeField. Value Description c : Creation a : Last access w : Last written 

Eine prägnantere VB.Net-Version, falls jemand interessiert ist

 Dim filePaths As Linq.IOrderedEnumerable(Of IO.FileInfo) = _ New DirectoryInfo("c:\temp").GetFiles() _ .OrderBy(Function(f As FileInfo) f.CreationTime) For Each fi As IO.FileInfo In filePaths ' Do whatever you wish here Next