Я ищу высокопроизводительный метод или библиотеку для сканирования всех файлов на диске или в заданном каталоге и получения их базовой статистики - имени файла, размера и даты модификации.
Я написал программу на Python, которая использует os.walk вместе с os.path.getsize для получения списка файлов, и она работает нормально, но не очень быстро. Я заметил, что одна из бесплатных программ, которые я скачал, выполняла такое же сканирование намного быстрее, чем моя программа.
Есть идеи по ускорению сканирования файлов? Вот мой код на Python, но имейте в виду, что я вовсе не женат на os.walk и совершенно готов использовать другие API-интерфейсы (включая собственные API-интерфейсы Windows), если есть лучшие альтернативы.
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
...
Я также должен отметить, что понимаю, что код Python, вероятно, нельзя так сильно ускорить; Меня особенно интересуют любые собственные API-интерфейсы, которые обеспечивают лучшую скорость.






Модуль os.path также имеет функцию обхода дерева каталогов. Я никогда не проводил никаких тестов, но вы можете попробовать. Однако я не уверен, что есть более быстрый способ, чем os.walk / os.path.walk в Python.
Что ж, я ожидал, что это будет задача, сильно связанная с вводом-выводом.
Таким образом, оптимизация на стороне Python была бы совершенно неэффективной; единственная оптимизация, о которой я мог подумать, - это какой-то другой способ доступа к файлам / листинга, чтобы уменьшить фактическое чтение из файловой системы.
Это, конечно, требует глубоких знаний файловой системы, которых у меня нет, и я не ожидаю, что разработчик python получит их при реализации os.walk.
Как насчет создания командной строки, а затем ввода «dir» и анализа результатов? Это может быть немного излишним, но если повезет, dir прилагает некоторые усилия для такой оптимизации.
Кажется, что os.walk был значительно улучшился в python 2.5, поэтому вы можете проверить, используете ли вы эту версию.
Помимо этого, кто-то уже сравнивал скорость os.walk с ls и заметил явное продвижение последнего, но не в том диапазоне, который фактически оправдал бы его использование.
Спасибо, Оле, я использую Python 2.5.
Когда вы посмотрите на код os.walk, вы увидите, что там не так много жира, который нужно обрезать.
Например, следующая команда всего на волосок быстрее, чем os.walk.
import os
import stat
listdir= os.listdir
pathjoin= os.path.join
fstat= os.stat
is_dir= stat.S_ISDIR
is_reg= stat.S_ISREG
def yieldFiles( path ):
for f in listdir(path):
nm= pathjoin( path, f )
s= fstat( nm ).st_mode
if is_dir( s ):
for sub in yieldFiles( nm ):
yield sub
elif is_reg( s ):
yield f
else:
pass # ignore these
Следовательно, накладные расходы должны быть в самом модуле os. Вам придется прибегнуть к прямым вызовам Windows API.
Посмотрите на Python для расширений Windows.
Возможно, вы захотите взглянуть на код некоторых систем управления версиями Python, таких как Mercurial или Bazaar. Они потратили много времени на то, чтобы придумать способы быстрого просмотра дерева каталогов и обнаружения изменений (или «поиска базовой статистики о файлах»).
Мне интересно, не хотите ли вы сгруппировать свои операции ввода-вывода.
Например, если вы проходите по плотному дереву каталогов с тысячами файлов, вы можете попробовать поэкспериментировать с обходом всего дерева и сохранением всех местоположений файлов, а затем перебрать их (в памяти) и получить статистику файлов.
Если ваша ОС хранит эти два данных в разных местах (структура каталогов в одном месте, статистика файлов в другом), это может быть значительной оптимизацией.
В любом случае, я бы попробовал это, прежде чем копать дальше.
Это лишь частичная помощь, больше похожая на указатели; тем не мение:
Я считаю, что вам нужно сделать следующее:
fp = open("C:/$MFT", "rb")
используя учетную запись, которая включает разрешения SYSTEM, потому что даже в качестве администратора вы не можете открыть «главную таблицу файлов» (своего рода таблицу inode) файловой системы NTFS. После того, как вам это удастся, вам просто нужно будет найти в Интернете информацию, которая объясняет структуру каждой записи файла (я считаю, что обычно это 1024 байта на файл на диске, который включает в себя основное имя пути к файлу), и вперед для сверхвысоких скоростей чтения структуры диска.
Часть заголовка сообщения "для окон" могла быть актуальной ;-) Возиться с MFT звучит немного странно, но я немного покопаюсь, чтобы увидеть, легко ли с этим форматом поиграться.
Используйте модуль scandir python (ранее betterwalk) на github от Бена Хойта.
http://github.com/benhoyt/scandir
Это намного быстрее, чем прогулка на Python, но использует тот же синтаксис. Просто импортируйте scandir и замените os.walk () на scandir.walk (). Вот и все. Это самый быстрый способ просмотра каталогов и файлов в Python.
Scandir входит в стандартную библиотеку начиная с Python 3.5.
Полезно знать .. спасибо Zenadix. К сожалению, я все еще использую Python 2.7.
Python 3.5 только что представил os.scandir (см. PEP-0471), который позволяет избежать ряда ненужных системных вызовов, таких как stat() и GetFileAttributes(), чтобы обеспечить значительно более быстрый итератор файловой системы.
os.walk() теперь будет реализован с использованием os.scandir() в качестве итератора, поэтому вы должны увидеть потенциально большие улучшения производительности, продолжая использовать os.walk().
Пример использования:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
os.path.walk () довольно неуклюжий и удаляется в Python 3, поэтому, пожалуйста, не используйте его.