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

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

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

Вот ссылка MSDN: msdn.microsoft.com/en-us/library/07wt70x2.aspx «Порядок возвращаемых имен файлов не гарантируется; используйте метод Sort, если требуется определенный порядок сортировки».

Ron 17.03.2018 00:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
65
1
149 506
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

От msdn:

The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required.

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

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

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

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

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

По умолчанию это порядок, в котором их возвращает файловая система. Если вы используете NTFS, они будут отсортированы по альфа-каналу, но если вы используете FAT32, они будут возвращены в порядке таблицы (т. Е. В более или менее порядке создания) .

Brad Wilson 10.09.2008 00:43

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

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

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

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

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

Ответ принят как подходящий

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

Нет LINQ в .Net2.0, но пока что это лучший ответ.

Joel Coehoorn 10.09.2008 00:49

Мне пришлось отменить ответ, потому что, когда я вернулся сегодня, чтобы реализовать его, метод .Net 2.0 называется .GetFileSystemEntries и он по-прежнему возвращает только массив строк.

Joel Coehoorn 10.09.2008 20:15

Джоэл, вы смотрите не на тот объект. System.IO.Directory имеет метод GetFileSystemEntries. Мое предложение заключалось в том, чтобы вместо этого использовать System.IO.DirectoryInfo, в котором есть метод GetFileSystemInfos. Надеюсь это поможет.

Ian Nelson 11.09.2008 12:33

Технически вы можете выполнять LINQ-to-Objects в .NET 2, и это все, что вам нужно для такого рода сортировки. albahari.com/nutshell/linqbridge.aspx

Joel Mueller 01.04.2010 07:17

Для LINQ-happy вы можете сделать это за один вызов: new DirectoryInfo(directory).GetFileSystemInfos().OrderBy(f => f.CreationTime). Потрясающие!

ashes999 17.11.2011 20:31

@ ashes999 - довольный LINQ или довольный плотным / кратким кодом? Мне лично очень нравится объединять операторы в цепочку так, как вы предлагаете, но это может усложнить чтение / отладку.

Ian Nelson 18.11.2011 00:58

@IanNelson Мне нравится лаконичный, читаемый код. Как только вы поймете LINQ, его легко понять (хотя вы не можете его отлаживать).

ashes999 18.11.2011 01:27

di.GetFileSystemInfos() также предоставит вам подкаталоги, если вам нужны только файлы, используйте di.GetFiles(), который возвращает FileInfo[], который также имеет свойство CreationTime.

CrnaStena 18.02.2015 22:32

Зачем использовать GetFileSystemInfos? DirectoryInfo не хватило?

S.Serpooshan 03.12.2017 15:32

@ S.Serp Недостаточно, если вам нужна подробная информация о файлах в каталоге. Ни одно из свойств класса DirectoryInfo не предоставляет подробную информацию о файлах, вам необходимо вызвать один из его методов, например GetFileSystemInfos или более новый EnumerateFileSystemInfos, который не был доступен в .NET 2.0.

Ian Nelson 07.12.2017 17:13

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

Я отредактировал пример кода, потому что Array.Sort нужен экземпляр DateComparer, иначе мы получим ошибку «DateComparer - это тип, который нельзя использовать как выражение». Спасибо за код, так как он был почти готов к использованию.

AlfonsoML 02.06.2012 14:26

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

Привет, Крис, комментарий в коде неверный? Вы указываете сортировку по времени создания, но LastWriteTime используется не CreationTime? Только что понял, как после лица этот комментарий!

AidanO 22.06.2011 15:28

Просто идея. Мне нравится находить легкий выход и пробовать повторно использовать уже имеющиеся ресурсы. если бы мне пришлось сортировать файлы, я бы просто создал процесс и сделал 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

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

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

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

Другие вопросы по теме