Ответ 1
Я понимаю, что это старый пост, но есть проект в исходной кузнице, который делает именно то, что вы просите, и исходный код доступен.
Вы можете найти проект здесь: NTFS-Search
Я пытаюсь ускорить перечисление каталога в С++, где я возвращаюсь в подкаталоги. В настоящее время у меня есть приложение, которое тратит 95% своего времени в API FindFirst/FindNextFile, и для перечисления всех файлов на данном томе требуется несколько минут. Я знаю, что это можно сделать быстрее, потому что есть приложение, которое делает: Все. Он перечисляет весь мой диск за считанные секунды.
Как я могу выполнить что-то вроде этого?
Я понимаю, что это старый пост, но есть проект в исходной кузнице, который делает именно то, что вы просите, и исходный код доступен.
Вы можете найти проект здесь: NTFS-Search
"Все" обращается к информации каталога на более низком уровне, чем API Win32 FindFirst/FindNext.
Я считаю, что он читает и интерпретирует структуры NTFS MFT напрямую и что это одна из основных причин его производительности. Это также объясняет, почему для этого требуются привилегии администратора и почему "все" индексирует только локальные или удаленные тома NTFS (например, не сетевые диски).
Пара других утилит, которые делают подобные вещи:
Небольшая обратная инженерия с отладчиком на этих инструментах может дать вам некоторое представление о тех методах, которые они используют.
"Все" строит индекс в фоновом режиме, поэтому запросы против индекса не являются самой файловой системой.
Существует несколько улучшений - по крайней мере, по прямому алгоритму:
Во-первых, поиск по ширине по глубине. То есть, перечислите и обработайте все файлы в одной папке, прежде чем переходить в найденные подпапки. Это улучшает локальность - обычно много.
В Windows 7/W2K8R2 вы можете использовать FindFirstFileEx
с FindExInfoBasic
, при этом основное ускорение пропускает короткое имя файла в файловых системах NTFS, где это разрешено.
Отдельные потоки помогают, если вы перечисляете разные физические диски (а не только диски). Для того же диска это помогает, только если это SSD ( "нулевое время поиска" ), или вы тратите значительное время на обработку имени файла (по сравнению с временем, затраченным на доступ к диску).
[edit] Wikipedia на самом деле есть некоторые комментарии - В основном, они пропускают слой абстракции файловой системы и напрямую обращаются к NTFS. Таким образом, они могут выполнять пакетные вызовы и пропускать дорогостоящие службы файловой системы - например, проверять ACL.
Хорошей отправной точкой будет Техническая ссылка NTFS на MSDN.
Если вы делаете это на NTFS, здесь lib для доступа с низким уровнем доступа: NTFSLib.
Вы можете перечислить все записи файлов в $MFT, каждый из которых представляет реальный файл на диске. Вы можете получить все атрибуты файла из записи, включая $DATA.
Это может быть самый быстрый способ перечислить все файлы/каталоги на томах NTFS, файлы 200 тыс. ~ 300 тыс. в минуту, как я тестировал.
Не перезаписывайте немедленно, сохраняйте список каталогов, которые вы найдете, и погрузитесь в них, когда закончите. Вы хотите сделать линейный доступ к каждому каталогу, чтобы использовать локальность ссылки и любое кэширование ОС.
Если вы уже делаете все возможное, чтобы получить максимальную скорость от API, следующим шагом будет сделать низкоуровневые обращения к диску и обойти Windows в целом. Вы можете получить руководство от NTFS-драйверов для Linux или, возможно, вы можете использовать его напрямую.