2009-07-29 18 views
19

Mam następujący kodJak sortować tablicę FileInfo []

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

chciałbym posortować listę według nazwy pliku.

Jak to zrobić, tak szybko i łatwo, jak to możliwe, używając .net v2.

+0

BTW Explorer nazwy sortowania przy użyciu naturalnych porównania liczb, więc jeśli chcesz osiągnąć podobne zachowanie, musisz napisać własny komparator, który podzieli nazwy na ciągi i liczby, i porówna je osobno. – arbiter

Odpowiedz

38

połączeń Array.sort, przechodzącą w delegata porównania:

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

W języku C# 3 staje nieco prostsze:

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

Albo można użyć StringComparer jeśli chcesz używać wielkości liter porządek:

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

(lub użyć string.Compare(x.Name, y.Name, true), lub jednej z wielu innych sposobów porównywania ciągów :)

+2

Mówiąc o C# 3.0, metoda OrderBy jest jeszcze prostsza ... –

+2

@Thomas - ale to nie robi sortowania w miejscu, co jest (wierzę), co OP chce –

+0

Dodałbym tylko, że można użyć vs2008, by celować w 2.0 przy użyciu składni 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); 

Ale i tak myślę, że wynik GetFiles jest już sortowane według nazwy ...

+0

"Ale w każdym razie myślę, że wynik GetFiles jest już posortowany według nazwy ..." - z MSDN: kolejność zwróconych nazw plików nie jest gwarantowana –

+0

GetFiles zwraca pliki posortowane według nazwy tylko na dyskach NTFS, ponieważ NTFS przechowuje nazwy jako drzewo binarne! Nie dotyczy to systemu plików FAT lub innego systemu plików. Dlatego zawsze musisz użyć sortowania, aby mieć pewność, że dane wyjściowe zostaną posortowane. – arbiter

+0

@Marc: dobry punkt! @arbiter: dzięki za wyjaśnienie –

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

W każdej operacji porównywania dzieje się bardzo dużo rozgałęzień, więc po prostu nie stwórz singla, zamiast tego specjalizowany porównawca dla każdego rodzaju sortowania? –

+0

Lub, zapisz delegata porównania w konstruktorze, na podstawie parametru CompareBy, a następnie po prostu wykonaj delegata w funkcji Porównaj. – wageoghe

Powiązane problemy