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

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

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

Ответ 1

Если вам интересны свойства таких файлов, как 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() сохраняется.

Ответ 2

Вот решение 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)

Ответ 3

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

Ответ 4

Dim Files() As String
Files = System.IO.Directory.GetFiles("C:\")
Array.Sort(Files)

Ответ 5

От msdn:

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

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

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

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

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

Ответ 10

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

Ответ 11

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

Ответ 12

Просто идея. Мне нравится найти простой выход и попробовать использовать уже имеющиеся ресурсы. если бы я сортировал файлы, я бы просто создал процесс и сделал 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, я получу это, вызвав syscall. И это БЫСТРО. Я просто ленивый парень;)

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

/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

Ответ 13

Более сжатая версия 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