2009-07-29 9 views
19

J'ai le code suivantComment trier un tableau de FileInfo []

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

Je voudrais trier la liste par nom de fichier.

Comment cela est-il fait, aussi rapidement et facilement que possible en utilisant .net v2.

+0

BTW, les noms de tri Explorer à l'aide de comparaison de nombre naturel, donc Si vous voulez obtenir un comportement similaire, vous devez écrire votre propre comparateur qui divisera les noms en chaînes et en blocs de nombres, et les comparera séparément. – arbiter

Répondre

38

Appel Array.Sort, en passant un délégué de comparaison:

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

En C# 3 cela devient un peu plus simple:

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

Ou vous pouvez utiliser un StringComparer si vous souhaitez utiliser un insensible à la casse ordre de tri:

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

(ou utiliser string.Compare(x.Name, y.Name, true), ou l'une des nombreuses autres façons de comparer les chaînes :)

+2

En parlant de C# 3.0, la méthode OrderBy est encore plus simple ... –

+2

@Thomas - mais cela ne fait pas un tri sur place, ce qui est (je crois) ce que l'OP veut –

+0

Je voudrais seulement ajouter qu'il est possible d'utiliser vs2008 pour cibler 2.0 en utilisant la syntaxe 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); 

Mais de toute façon je pense que le résultat de GetFiles est déjà trié par nom ...

+0

"De toute façon je pense que le résultat de GetFiles est déjà trié par nom ..." - MSDN: L'ordre des noms de fichiers retournés n'est pas garanti –

+0

GetFiles retourne les fichiers triés par nom uniquement sur les lecteurs NTFS, car NTFS stocke les noms comme arbre binaire! Ceci n'est pas valable pour FAT ou tout autre système de fichiers. Donc, vous devez toujours utiliser tri pour être sûr que la sortie est triée. – arbiter

+0

@Marc: bon point! @arbiter: merci pour l'explication –

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

Il y a énormément de branchements à l'intérieur de chaque opération de comparaison, pourquoi ne pas simplement instancier un seul, un comparateur spécialisé pour chaque type de tri à la place? –

+0

Ou, enregistrez un délégué de comparaison dans le constructeur, basé sur le paramètre CompareBy, puis exécutez simplement le délégué dans la fonction de comparaison. – wageoghe

Questions connexes