Как я могу быстро перечислить каталоги на Win32? - PullRequest
26 голосов
/ 25 марта 2010

Я пытаюсь ускорить перечисление каталогов в C ++, где я возвращаюсь в подкаталоги. В настоящее время у меня есть приложение, которое тратит 95% своего времени в API FindFirst / FindNextFile, и для перечисления всех файлов на данном томе требуется несколько минут. Я знаю, что это можно сделать быстрее, потому что есть приложение, которое делает: Все . Он перечисляет весь мой диск в секундах.

Как я могу сделать что-то подобное?

Ответы [ 6 ]

8 голосов
/ 08 марта 2011

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

Вы можете найти проект здесь: NTFS-Search

6 голосов
/ 25 марта 2010

«Все» обращается к информации каталога на более низком уровне, чем Win32 FindFirst / FindNext API.

Я считаю, что он читает и интерпретирует структуры NTFS MFT напрямую, и это является одной из основных причин его производительности. Кроме того, для этого требуются права администратора и почему «Все» индексирует только локальные или съемные тома NTFS (например, не сетевые диски).

Пара других утилит, которые делают подобные вещи:

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

5 голосов
/ 25 марта 2010

«Все» создает индекс в фоновом режиме, поэтому запросы относятся к индексу, а не к самой файловой системе.

Необходимо внести несколько улучшений - по крайней мере, по прямому алгоритму:

Сначала поиск по ширине по поиску по глубине. То есть перечислите и обработайте все файлы в одной папке, прежде чем переходить в найденные вами подпапки. Это улучшает местность - обычно очень много.

В Windows 7 / W2K8R2 вы можете использовать FindFirstFileEx с FindExInfoBasic, главное ускорение - пропуск короткого имени файла в файловых системах NTFS, где это включено.

Отдельные потоки помогают, если вы перечисляете разные физические диски (не только диски). Для того же диска это помогает, только если это SSD («нулевое время поиска») или вы тратите значительное время на обработку имени файла (по сравнению с временем, затраченным на доступ к диску).


[редактировать] Википедия на самом деле есть некоторые комментарии - По сути, они пропускают уровень абстракции файловой системы и получают прямой доступ к NTFS. Таким образом, они могут пакетировать вызовы и пропускать дорогостоящие сервисы файловой системы, такие как проверка ACL.

Хорошей отправной точкой была бы техническая справка NTFS в MSDN.

2 голосов
/ 25 марта 2010

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

1 голос
/ 07 сентября 2012

Если вы делаете это в NTFS, вот библиотека для низкоуровневого доступа: NTFSLib .

Вы можете перечислять все записи в $ MFT, каждая из которых представляет собой реальный файл на диске. Вы можете получить все атрибуты файла из записи, включая $ DATA.

Это может быть самый быстрый способ перечисления всех файлов / каталогов на томах NTFS, 200–300 тыс. Файлов в минуту, как я тестировал.

0 голосов
/ 25 марта 2010

Если вы уже делаете все возможное, чтобы получить максимальную скорость от API, следующий шаг - сделать низкоуровневый доступ к диску и вообще обойти Windows.Вы можете получить некоторые рекомендации от NTFS драйверов для Linux , или, возможно, вы можете использовать их напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...