Сортировка Directory.GetFiles () - PullRequest
       34

Сортировка Directory.GetFiles ()

64 голосов
/ 10 сентября 2008

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

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

Ответы [ 13 ]

108 голосов
/ 10 сентября 2008

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

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

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

12 голосов
/ 10 ноября 2008

В .NET 2.0 вам нужно использовать Array.Sort для сортировки 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);
                                    });
12 голосов
/ 29 сентября 2008

Вот решение 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)
7 голосов
/ 10 сентября 2008

Dim Files() As String
Files = System.IO.Directory.GetFiles("C:\")
Array.Sort(Files)
6 голосов
/ 10 сентября 2008

С MSDN :

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

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

3 голосов
/ 12 декабря 2013

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

For Each fi As IO.FileInfo In filePaths.reverse
  ' Do whatever you wish here
Next
3 голосов
/ 10 сентября 2008

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

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

msdn info Интерфейс IComparer

3 голосов
/ 10 сентября 2008

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

Затем вы можете использовать DefaultView из таблицы данных и отсортировать каталог с помощью метода .Sort.

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

2 голосов
/ 10 сентября 2008

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

2 голосов
/ 10 сентября 2008

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

...