Метод быстрого сканирования файлов / каталогов для windows?

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

Я написал программу на 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-интерфейсы, которые обеспечивают лучшую скорость.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
9 136
9

Ответы 9

Модуль os.path также имеет функцию обхода дерева каталогов. Я никогда не проводил никаких тестов, но вы можете попробовать. Однако я не уверен, что есть более быстрый способ, чем os.walk / os.path.walk в Python.

os.path.walk () довольно неуклюжий и удаляется в Python 3, поэтому, пожалуйста, не используйте его.

Benjamin Peterson 29.12.2008 19:45

Что ж, я ожидал, что это будет задача, сильно связанная с вводом-выводом. Таким образом, оптимизация на стороне Python была бы совершенно неэффективной; единственная оптимизация, о которой я мог подумать, - это какой-то другой способ доступа к файлам / листинга, чтобы уменьшить фактическое чтение из файловой системы. Это, конечно, требует глубоких знаний файловой системы, которых у меня нет, и я не ожидаю, что разработчик python получит их при реализации os.walk.

Как насчет создания командной строки, а затем ввода «dir» и анализа результатов? Это может быть немного излишним, но если повезет, dir прилагает некоторые усилия для такой оптимизации.

Кажется, что os.walk был значительно улучшился в python 2.5, поэтому вы можете проверить, используете ли вы эту версию.

Помимо этого, кто-то уже сравнивал скорость os.walk с ls и заметил явное продвижение последнего, но не в том диапазоне, который фактически оправдал бы его использование.

Спасибо, Оле, я использую Python 2.5.

Parand 31.12.2008 04:32

Когда вы посмотрите на код 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 звучит немного странно, но я немного покопаюсь, чтобы увидеть, легко ли с этим форматом поиграться.

Parand 31.12.2008 04:35

Используйте модуль scandir python (ранее betterwalk) на github от Бена Хойта.

http://github.com/benhoyt/scandir

Это намного быстрее, чем прогулка на Python, но использует тот же синтаксис. Просто импортируйте scandir и замените os.walk () на scandir.walk (). Вот и все. Это самый быстрый способ просмотра каталогов и файлов в Python.

Scandir входит в стандартную библиотеку начиная с Python 3.5.

Zenadix 22.09.2015 23:47

Полезно знать .. спасибо Zenadix. К сожалению, я все еще использую Python 2.7.

panofish 23.09.2015 03:53

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)

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