2009-07-29 18 views
19

Tengo el siguiente códigoCómo ordenar un arreglo de FileInfo []

DirectoryInfo taskDirectory = new DirectoryInfo(this.taskDirectoryPath); 
FileInfo[] taskFiles = taskDirectory.GetFiles("*" + blah + "*.xml"); 

quisiera ordenar la lista por nombre de archivo.

Cómo se hace esto, tan rápido y fácil como sea posible usando .net v2.

+0

Por cierto, el Explorador de nombres de orden mediante la comparación de número natural por lo que, si desea lograr un comportamiento similar, debe escribir su propio comparador que dividirá los nombres en cadenas y numerales de números, y los comparará por separado. – arbiter

Respuesta

38

llamada Array.Sort, pasando de un delegado de comparación:

Array.Sort(taskFiles, delegate(FileInfo f1, FileInfo f2) { 
    return f1.Name.CompareTo(f2.Name); 
}); 

En C# 3 esto se convierte un poco más sencillo:

Array.Sort(taskFiles, (f1, f2) => f1.Name.CompareTo(f2.Name)); 

O puede utilizar una StringComparer si desea utilizar una entre mayúsculas y minúsculas orden de clasificación:

Array.Sort(taskFiles, 
      (x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name)); 

(o utilizar string.Compare(x.Name, y.Name, true), o cualquiera de las muchas otras formas de cuerdas que comparan :)

+2

Hablando de C# 3.0, el método OrderBy es incluso más simple ... –

+2

@Thomas - pero eso no hace una clasificación in situ, que es (creo) lo que el OP quiere –

+0

Solo agregaría que es posible usar vs2008 para apuntar 2.0 usando la sintaxis de C# 3.0;) – kentaromiura

0
Comparison<FileInfo> comparison = new Comparison<FileInfo>(delegate(FileInfo a, FileInfo b) 
{ 
    return String.Compare(a.Name, b.Name); 
}); 

Array.Sort(taskFiles, comparison); 

Pero de todos modos creo que el resultado de GetFiles ya está ordenada por nombre ...

+0

"Pero, de todos modos, creo que el resultado de GetFiles ya está ordenado por nombre ...": de MSDN: no se garantiza el orden de los nombres de archivo devueltos –

+0

GetFiles devuelve archivos ordenados por nombre solo en unidades NTFS, porque NTFS almacena nombres como ¡árbol binario! Esto no es válido para FAT o cualquier otro sistema de archivos. Por lo tanto, siempre debe usar la ordenación para asegurarse de que la salida esté ordenada. – arbiter

+0

@Marc: ¡buen punto! @arbiter: gracias por la explicación –

9
Array.Sort(taskFiles, delegate (FileInfo x, FileInfo y) { 
    return string.Compare(x.Name,y.Name); 
}); 
0
public class FileComparer : IComparer 
     { 
      public enum CompareBy 
      { 
       Name /* a-z */, 
       LastWriteTime /* oldest to newest */, 
       CreationTime /* oldest to newest */, 
       LastAccessTime /* oldest to newest */, 
       FileSize /* smallest first */, 

      } 
      // default comparison 
      int _CompareBy = (int)CompareBy.Name; 
      public FileComparer() 
      { 
      } 

      public FileComparer(CompareBy compareBy) 
      { 
       _CompareBy = (int)compareBy; 
      } 
      int IComparer.Compare(object x, object y) 
      { 
       int output = 0; 
       DirectoryInfo file1 = new DirectoryInfo(x.ToString()); 
       DirectoryInfo file2 = new DirectoryInfo(y.ToString()); 
       switch(_CompareBy) 
       { 
        case (int)CompareBy.LastWriteTime: 
         output = DateTime.Compare(file1.LastWriteTime, file2.LastWriteTime); 
         break; 
        case (int)CompareBy.CreationTime: 
         output = DateTime.Compare(file1.CreationTime, file2.CreationTime); 
         break; 
        case (int)CompareBy.LastAccessTime: 
         output = DateTime.Compare(file1.LastAccessTime, file2.LastAccessTime); 
         break; 
    //    case (int)CompareBy.FileSize: 
    //     output = Convert.ToInt32(file1.Length - file2.Length); 
    //     break; 
        case (int)CompareBy.Name: 
        default: 
         output = (new CaseInsensitiveComparer()).Compare(file1.Name, file2.Name); 
         break; 
       } 
       return output; 
      } 
     } 

/////////////////////////////////// 
ArrayList list=new ArrayList();   
      string folder = @"D:\DVRData\ICICI\Transaction\21-Dec-08\08_51_23_2231"; 
      string[] files = Directory.GetFiles(folder);    
      IComparer comp = new FileComparer(FileComparer.CompareBy.CreationTime); 
      Array.Sort(files, comp); 
      foreach(string file in files) 
      { 
       list.Add(file); 
      } 
+1

Hay una gran cantidad de ramificaciones en cada operación de comparación, ¿por qué no crear una sola instancia? comparador especializado para cada tipo de clasificación en su lugar? –

+0

O, guarde un delegado de comparación en el constructor, basado en el parámetro CompareBy y luego simplemente ejecute el delegado en la función Comparar. – wageoghe