Получить файлы из каталога и подкаталогов быстро упорядочить по последней дате создания

1

Я ищу метод, который возьмет тип и каталог расширения файлов и вернет все файлы в этом каталоге и подкаталогах, упорядоченных по последней дате создания, то есть последним файлам.

До сих пор я определил следующий метод, который должен быть быстрым, но есть лучший способ сделать это, и мне нужно, чтобы он возвращал FileInfo, а не строку и упорядочивался, как описано выше.

public static IEnumerable<string> GetFileList(string fileSearchPattern, string rootFolderPath)
{
Queue<string> pending = new Queue<string>();
pending.Enqueue(rootFolderPath);
string[] tmp;
while (pending.Count > 0)
{
    rootFolderPath = pending.Dequeue();
    tmp = Directory.GetFiles(rootFolderPath, fileSearchPattern);
    for (int i = 0; i < tmp.Length; i++)
    {
        yield return tmp[i];
    }
    tmp = Directory.GetDirectories(rootFolderPath);
    for (int i = 0; i < tmp.Length; i++)
    {
        pending.Enqueue(tmp[i]);
    }
}
}
Теги:

3 ответа

1

Когда я исследовал это проблемное пространство, я обнаружил, что это не fast способ сделать это. Причина в том, какой бы подход вы ни выбрали, вам нужно перейти в операционную систему для списка файлов в каталоге. И файловая система не кэширует/не индексирует способ поиска. Таким образом, вам в конечном итоге нужно пересканировать файловую систему самостоятельно.

Однако, если у вас есть необработанная информация, вы можете индексировать ее самостоятельно.

1

Ниже будет работать для ваших целей. Вы хотите использовать Directory.EnumerateFiles(...), чтобы список файлов мог использовать меньше памяти спереди. Он будет искать следующий элемент, только когда вы попросите его, а не загрузите всю коллекцию в память в начале.

Directory.EnumerateFiles(rootFolderPath, fileSearchPattern, System.IO.SearchOption.AllDirectories).OrderBy(file => new FileInfo(file).CreationTime)

Еще одно соображение. Поскольку вы делаете довольно слепой поиск через файловую систему, если вы попытаетесь перечислить файл и выбрано исключение, это приведет к недействительности перечислителя, что приведет к его завершению без завершения. Я опубликовал решение этой проблемы здесь

  • 0
    Ленивая загрузка поможет в этом отношении? ОП все равно пытается получить все файлы, поэтому отсроченное выполнение здесь не приведет к повышению производительности.
  • 0
    Ленивая загрузка, вероятно, не правильная формулировка. Использование EnumerateFiles (...) использует меньший объем памяти и быстрее возвращается, только когда вы действительно ищете, когда вы действительно запросите следующий элемент. Я уточнил свой ответ, чтобы указать это.
0

Directory.GetFiles имеет возможность поиска рекурсивно.

Следующее должно работать, хотя я этого не пробовал.

    IEnumerable<FileInfo> GetFileList(string directory, string extension)
    {
        return Directory.GetFiles(directory, "*" + extension, SearchOption.AllDirectories)
            .Select(f => new FileInfo(f))
            .OrderByDescending(f => f.CreationTime);
    } 
  • 0
    Это неэффективное решение, потому что Directory.GetFiles () будет ждать, пока он загрузит все файлы, прежде чем вернуться. вместо этого вы должны использовать Directory.EnumerateFiles (...).
  • 0
    Обычно я бы согласился, но мы упорядочиваем файлы по времени их создания, поэтому, возможно, нам все равно придется сначала загрузить все файлы.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню