Frage

System.IO.Directory.GetFiles() gibt a zurück string[].Was ist die Standardsortierreihenfolge für die zurückgegebenen Werte?Ich nehme es namentlich an, aber wenn ja, wie stark wirkt sich die aktuelle Kultur darauf aus?Können Sie es in etwas wie das Erstellungsdatum ändern?

Aktualisieren: MSDN weist darauf hin, dass die Sortierreihenfolge für .Net 3.5 nicht garantiert ist, aber die 2.0-Version der Seite sagt überhaupt nichts aus und keine der Seiten hilft Ihnen beim Sortieren nach Dingen wie Erstellungs- oder Änderungszeit.Diese Informationen gehen verloren, sobald Sie das Array haben (es enthält nur Zeichenfolgen).Ich könnte einen Vergleicher erstellen, der jede Datei überprüft, die er erhält, aber das bedeutet, dass ich wiederholt auf das Dateisystem zugreifen muss, obwohl die Methode .GetFiles() dies vermutlich bereits tut.Scheint sehr ineffizient.

War es hilfreich?

Lösung

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, z. B.:

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

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

Andere Tipps

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

Darüber hinaus können Sie einen Comparer-Delegaten verwenden, um zu vermeiden, dass nur für den Vergleich eine Klasse deklariert werden muss:

DirectoryInfo dir = new DirectoryInfo(path);
FileSystemInfo[] files = dir.GetFileSystemInfos();

// sort them by creation time
Array.Sort<FileSystemInfo>(files, delegate(FileSystemInfo a, FileSystemInfo b)
                                    {
                                        return a.LastWriteTime.CompareTo(b.LastWriteTime);
                                    });

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

Erstellen Sie zunächst eine Klasse 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 Vergleicher beim Sortieren des Arrays:

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)

Aus msdn:

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

Der Sortieren() Die Methode ist die Standardmethode Array.Sort(), die IComparables (neben anderen Überladungen) aufnimmt. Wenn Sie also nach Erstellungsdatum sortieren, erfolgt die Lokalisierung basierend auf den Maschineneinstellungen.

Sie haben Recht, die Standardeinstellung ist mein Name aufsteigend.Die einzige Möglichkeit, die ich gefunden habe, ist die Sortierreihenfolge zu ändern, um eine Datentabelle aus der FileInfo-Sammlung zu erstellen.

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

Das ist ziemlich aufwändig und ziemlich langsam, aber ich hoffe, dass jemand eine bessere Lösung postet.

Sie können einen benutzerdefinierten iComparer implementieren, um die Sortierung durchzuführen.Lesen Sie die Dateiinformationen für Dateien und vergleichen Sie sie nach Belieben.

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.Danke schön.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

Der MSDN-Dokumentation gibt an, dass es keine Garantie für die Reihenfolge der Rückgabewerte gibt.Sie müssen die Methode Sort() verwenden.

Sie könnten eine benutzerdefinierte IComparer-Schnittstelle schreiben, um nach Erstellungsdatum zu sortieren, und sie dann an Array.Sort übergeben.Wahrscheinlich möchten Sie sich auch StrCmpLogical ansehen, das für die vom Explorer verwendete Sortierung verwendet wird (Zahlen korrekt mit Text sortieren).

Wenn Sie beispielsweise nach dem Erstellungsdatum sortieren möchten, müssen Sie wahrscheinlich DirectoryInfo.GetFiles verwenden und dann das resultierende Array mithilfe eines geeigneten Prädikats sortieren.

Nur eine Idee.Ich finde gerne einen einfachen Ausweg und versuche, bereits verfügbare Ressourcen wiederzuverwenden.Wenn ich Dateien sortieren würde, würde ich einfach einen Prozess erstellen und syscal auf „DIR [x:\Folders\SubFolders*.*] /s /b /on“ umstellen und die Ausgabe erfassen.

Mit dem DIR-Befehl 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 mir nicht sicher, ob D = By Date/Time LastModifiedDate oder FileCreateDate verwendet.Wenn die benötigte Sortierreihenfolge jedoch bereits im DIR-Befehl integriert ist, erhalte ich diese durch den Aufruf von syscall.Und es ist SCHNELL.Ich bin einfach der Faule ;)

Nach ein wenig Googeln habe ich einen Schalter zum Sortieren nach bestimmtem Datum/Uhrzeit gefunden: -

/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 Interesse hat

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top