Pregunta

System.IO.Directory.GetFiles() devuelve un string[].¿Cuál es el orden de clasificación predeterminado para los valores devueltos?Lo supongo por su nombre, pero si es así, ¿en qué medida le afecta la cultura actual?¿Puedes cambiarlo a algo como la fecha de creación?

Actualizar: MSDN señala que el orden de clasificación no está garantizado para .Net 3.5, pero la versión 2.0 de la página no dice nada en absoluto y ninguna de las páginas le ayudará a ordenar por cosas como el tiempo de creación o modificación.Esa información se pierde una vez que tienes la matriz (solo contiene cadenas).Podría crear un comparador que verificaría cada archivo que obtiene, pero eso significa acceder al sistema de archivos repetidamente cuando presumiblemente el método .GetFiles() ya lo hace.Parece muy ineficiente.

¿Fue útil?

Solución

Si está interesado en las propiedades de archivos como CreationTime, entonces tendría más sentido usar System.IO.DirectoryInfo.GetFileSystemInfos().Luego puede ordenarlos usando uno de los métodos de extensión en System.Linq, por ejemplo:

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

Editar: lo siento, no noté la etiqueta .NET2.0, así que ignore la clasificación LINQ.Sin embargo, la sugerencia de utilizar System.IO.DirectoryInfo.GetFileSystemInfos() sigue siendo válida.

Otros consejos

En .NET 2.0, necesitará usar Array.Sort para ordenar FileSystemInfos.

Además, puedes usar un delegado de Comparador para evitar tener que declarar una clase solo para la comparación:

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

Aquí está la solución VB.Net que he usado.

Primero haz una clase para comparar fechas:

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

Luego use el comparador mientras ordena la matriz:

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)

De msdn:

No se garantiza el orden de los nombres de los archivos devueltos;utilice el método Sort() si se requiere un orden de clasificación específico.

El Clasificar() El método es el estándar Array.Sort(), que acepta IComparables (entre otras sobrecargas), por lo que si ordena por fecha de creación, manejará la localización según la configuración de la máquina.

Tienes razón, el valor predeterminado es mi nombre asc.La única forma que he encontrado de cambiar el orden de clasificación es crear una tabla de datos de la colección FileInfo.

Luego puede utilizar DefaultView de la tabla de datos y ordenar el directorio con el método .Sort.

Esto es bastante complicado y bastante lento, pero espero que alguien publique una solución mejor.

Puede implementar iComparer personalizado para realizar la clasificación.Lea la información del archivo para los archivos y compárelo como desee.

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

información msdn interfaz IComparer

Una versión más concisa de VB.Net... es muy buena.Gracias.Para recorrer la lista en orden inverso, agregue el método inverso...

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

El Documentación de MSDN afirma que no hay garantía de ningún pedido sobre los valores devueltos.Tienes que usar el método Sort().

Podría escribir una interfaz IComparer personalizada para ordenar por fecha de creación y luego pasarla a Array.Sort.Probablemente también quieras ver StrCmpLogical, que es lo que se utiliza para realizar la clasificación que utiliza Explorer (clasificar números correctamente con texto).

Si desea ordenar por algo como la fecha de creación, probablemente necesite usar DirectoryInfo.GetFiles y luego ordenar la matriz resultante usando un Predicado adecuado.

Solo una idea.Me gusta encontrar una salida fácil e intentar reutilizar los recursos que ya están disponibles.Si tuviera que ordenar archivos, simplemente crearía un proceso y haría syscal en "DIR [x:\Folders\SubFolders*.*] /s /b /on" y capturaría el resultado.

Con el comando DIR del sistema puedes ordenar por:

/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

NO ESTOY SEGURO SI D = Por fecha/hora está usando LastModifiedDate o FileCreateDate.Pero si el orden de clasificación necesario ya está integrado en el comando DIR, lo obtendré llamando a syscall.Y es RÁPIDO.Sólo soy el tipo vago;)

Después de buscar un poco en Google, encontré un cambio para ordenar por fecha/hora en particular: -

/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 versión más concisa de VB.Net, si alguien está interesado

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top