2009-07-29 13 views
19

ich den folgenden CodeWie ein Array von Fileinfo sortieren []

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

Ich möchte sortieren Sie die Liste nach Dateinamen haben.

Wie erfolgt dies, so schnell und einfach wie möglich mit .net v2.

+0

BTW, Explorer Art Namen natürliche Zahl Vergleich, so verwenden Wenn Sie ein ähnliches Verhalten erzielen möchten, müssen Sie einen eigenen Vergleicher erstellen, der Namen in Strings und Zahlenblöcke aufteilt und sie separat vergleicht. – arbiter

Antwort

38

Anruf Array.Sort, in einem Vergleich Delegierten vorbei:

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

In C# 3 wird dies etwas einfacher:

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

Oder können Sie eine StringComparer verwenden, wenn Sie eine verwenden möchten Groß- und Kleinschreibung Sortierreihenfolge:

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

(oder string.Compare(x.Name, y.Name, true), oder eine der vielen anderen Möglichkeiten zu vergleichen Strings :)

+2

Apropos C# 3.0, die OrderBy-Methode ist noch einfacher ... –

+2

@Thomas - aber das macht nicht eine In-Place-Sortierung, die (was ich glaube) was das OP will –

+0

Ich würde nur hinzufügen, dass es möglich ist, vs2008 2.0 mit C# 3.0 Syntax zu verwenden;) – kentaromiura

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

Array.Sort(taskFiles, comparison); 

Aber trotzdem denke ich, das Ergebnis GetFiles bereits nach Namen sortiert wird ...

+0

"Aber ich denke sowieso, das Ergebnis von GetFiles ist bereits nach Namen sortiert ..." - von MSDN: Die Reihenfolge der zurückgegebenen Dateinamen ist nicht garantiert –

+0

GetFiles Rückgabedateien nur nach NTFS-Laufwerken sortiert, weil NTFS Namen speichert als Binärbaum! Dies gilt nicht für FAT oder ein anderes Dateisystem. Sie müssen also immer sort verwenden, um sicherzustellen, dass die Ausgabe sortiert ist. – arbiter

+0

@Marc: guter Punkt! @arbiter: danke für die Erklärung –

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

Es gibt eine Menge Verzweigungen in jeder Vergleichsoperation, warum nicht einfach nur eine Instanz instantiieren, Spezieller Vergleich für jede Sortierart? –

+0

Oder speichern Sie einen Vergleichsdelegaten im Konstruktor, basierend auf dem CompareBy-Parameter, und führen Sie dann den Delegaten nur in der Compare-Funktion aus. – wageoghe