Domanda

System.IO.Directory.GetFiles() restituisce a string[].Qual è l'ordinamento predefinito per i valori restituiti?Presumo per nome, ma se sì, quanto incide la cultura attuale?Puoi cambiarlo in qualcosa come la data di creazione?

Aggiornamento: MSDN sottolinea che l'ordinamento non è garantito per .Net 3.5, ma la versione 2.0 della pagina non dice nulla e nessuna delle due pagine ti aiuterà a ordinare in base a elementi come l'ora di creazione o di modifica.Tali informazioni vengono perse una volta ottenuto l'array (contiene solo stringhe).Potrei creare un comparatore che controlli ogni file ottenuto, ma ciò significa accedere ripetutamente al file system quando presumibilmente il metodo .GetFiles() lo fa già.Sembra molto inefficiente.

È stato utile?

Soluzione

Se sei interessato alle proprietà dei file come CreationTime, allora avrebbe più senso utilizzare System.IO.DirectoryInfo.GetFileSystemInfos().È quindi possibile ordinarli utilizzando uno dei metodi di estensione in System.Linq, ad esempio:

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

Modifica: scusa, non ho notato il tag .NET2.0, quindi ignora l'ordinamento LINQ.Il suggerimento di utilizzare System.IO.DirectoryInfo.GetFileSystemInfos() è comunque valido.

Altri suggerimenti

In .NET 2.0, dovrai utilizzare Array.Sort per ordinare FileSystemInfos.

Inoltre, puoi utilizzare un delegato Comparer per evitare di dover dichiarare una classe solo per il confronto:

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);
                                    });

Ecco la soluzione VB.Net che ho usato.

Per prima cosa crea una lezione per confrontare le date:

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

Quindi utilizzare il comparatore mentre si ordina l'array:

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)

Da msdn:

L'ordine dei nomi dei file restituiti non è garantito;utilizzare il metodo Sort() se è richiesto un ordinamento specifico.

IL Ordinare() Il metodo è lo standard Array.Sort(), che accetta IComparables (tra gli altri sovraccarichi), quindi se si ordina per data di creazione, gestirà la localizzazione in base alle impostazioni della macchina.

Hai ragione, il valore predefinito è il mio nome asc.L'unico modo che ho trovato per modificare l'ordinamento è creare un datatable dalla raccolta FileInfo.

È quindi possibile utilizzare DefaultView dal datatable e ordinare la directory con il metodo .Sort.

Questo è abbastanza coinvolgente e abbastanza lento, ma spero che qualcuno pubblichi una soluzione migliore.

Puoi implementare iComparer personalizzato per eseguire l'ordinamento.Leggi le informazioni sui file e confronta come preferisci.

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

informazioni msdn Interfaccia IComparer

Una versione VB.Net più concisa... è molto carina.Grazie.Per scorrere l'elenco in ordine inverso, aggiungere il metodo inverso...

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

IL Documentazione MSDN afferma che non vi è alcuna garanzia di alcun ordine sui valori restituiti.Devi usare il metodo Sort().

Potresti scrivere un'interfaccia IComparer personalizzata per ordinare in base alla data di creazione e quindi passarla a Array.Sort.Probabilmente vorrai anche dare un'occhiata a StrCmpLogical, che è ciò che viene utilizzato per eseguire l'ordinamento utilizzato da Explorer (ordinare correttamente i numeri con il testo).

Se vuoi ordinare in base a qualcosa come la data di creazione, probabilmente dovrai utilizzare DirectoryInfo.GetFiles e quindi ordinare l'array risultante utilizzando un predicato adatto.

Solo un'idea.Mi piace trovare una via d'uscita semplice e provare a riutilizzare le risorse già disponibili.se dovessi ordinare i file, creerei semplicemente un processo e trasformerei il syscal in "DIR [x:\Folders\SubFolders*.*] /s /b /on" e catturerei l'output.

Con il comando DIR del sistema puoi ordinare per:

/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

NON SONO SICURO SE D = By Date/Time utilizza LastModifiedDate o FileCreateDate.Ma se l'ordinamento necessario è già integrato nel comando DIR, lo otterrò chiamando syscall.Ed è VELOCE.Sono solo un ragazzo pigro ;)

Dopo aver cercato su Google ho trovato l'opzione per ordinare in base a data/ora particolari:-

/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

Una versione VB.Net più concisa, se qualcuno è interessato

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top