Сортировка Каталога.Заражен()


System.IO.Directory.GetFiles() возвращает a string[]. Каков порядок сортировки по умолчанию для возвращаемого значения? Я предполагаю по имени, но если да, то насколько это влияет на текущую культуру? Вы можете изменить его на что-то вроде даты создания?

обновление: MSDN указывает, что порядок сортировки не гарантируется для .Net 3.5, но версия 2.0 страницы вообще ничего не говорит, и ни одна страница не поможет вам Сортировать по таким вещам, как время создания или изменения. Эта информация теряется только у вас есть массив (он содержит только строки). Я мог бы построить компаратор, который будет проверять каждый файл, который он получает, но это означает многократный доступ к файловой системе, когда предположительно .Метод GetFiles () уже делает это. Кажется очень неэффективным.

13 60

13 ответов:

Если вы заинтересованы в свойствах файлов, таких как CreationTime, то было бы более целесообразно использовать System.IO.DirectoryInfo.GetFileSystemInfos(). Затем вы можете сортировать их используя один из методов расширения в системе.Linq, например:

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

Edit-извините, я не заметил тег .NET2.0, поэтому игнорируйте сортировку LINQ. Однако предложение использовать System.IO.DirectoryInfo.GetFileSystemInfos() по-прежнему остается в силе.

в .NET 2.0, вам нужно будет использовать массив.Сортировка для сортировки FileSystemInfos.

кроме того, вы можете использовать делегат Comparer, чтобы избежать необходимости объявлять класс только для сравнения:

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

вот VB.Net решение, которое я использовал.

сначала сделайте класс для сравнения дат:

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

затем используйте компаратор при сортировке массива:

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)

с msdn:

порядок возвращаемых имен файлов не гарантируется; используйте метод Sort (), если требуется определенный порядок сортировки.

The Sort () метод является стандартным массивом.Sort (), который принимает IComparables (среди других перегрузок), поэтому если вы сортируете по дате создания, он будет обрабатывать локализацию на основе настроек машины.

вы можете реализовать пользовательский iComparer для сортировки. Прочитайте информацию о файле для файлов и сравнить, как вам нравится.

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

в MSDN информация интерфейс интерфейса icomparer

более лаконичный VB.Net version...is очень мило. Спасибо. Чтобы пройти список в обратном порядке, добавьте обратный метод...

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

The Примечание заявляет, что нет никакой гарантии какого-либо порядка на возвращаемых значениях. Вы должны использовать метод Sort ().

вы правы, по умолчанию-мое имя возр. Единственный способ, который я нашел, чтобы изменить порядок сортировки, чтобы создать datatable из коллекции FileInfo.

затем вы можете использовать DefaultView из datatable и сортировать каталог с помощью .Метод сортировки.

Это довольно сложно и довольно медленно, но я надеюсь, что кто-то опубликует лучшее решение.

вы можете написать пользовательский интерфейс IComparer для сортировки по дате создания, а затем передать его в массив.Род. Вероятно, вы также хотите посмотреть на StrCmpLogical, который используется для сортировки проводника (сортировка чисел правильно с текстом).

Если вы хотите отсортировать что-то вроде даты создания, вам, вероятно, нужно использовать DirectoryInfo.GetFiles, а затем отсортировать полученный массив с помощью подходящего предиката.

просто идея. Мне нравится находить легкий выход и пытаться повторно использовать уже имеющиеся ресурсы. если бы я сортировал файлы, я бы просто создал процесс и сделал syscal в "DIR [x:\Folders\SubFolders*.*] /s/b / on" и захват вывода.

С помощью команды DIR системы вы можете сортировать по :

/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

Я не уверен, что D = по дате/времени использует LastModifiedDate или FileCreateDate. Но если необходимый порядок сортировки уже встроен в команду DIR, я получу это Вызов системного вызова. И это быстро. Я просто ленивый парень ;)

после небольшого googling я нашел переключатель для сортировки по конкретной дате / времени: -

/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

более лаконичный VB.Net версия, если кому интересно

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