Лучший способ получить список файлов большой директории на python?
У меня безумный большой каталог. Мне нужно получить список файлов через Python.
В коде мне нужно получить итератор, а не список. Так что это не работа:
os.listdir
glob.glob (uses listdir!)
os.walk
Я не могу найти хорошую библиотеку. Помогите! Может быть, C++ lib?
7 ответов
Если у вас есть каталог, который слишком велик для быстрого чтения libc readdir(), вы, вероятно, захотите взглянуть на вызов ядра getdents () ( http://www.kernel.org/doc/man-pages/online/pages/man2/getdents.2.html). Я столкнулся с подобной проблемой и написал длинный пост в блоге об этом.
http://www.olark.com/spw/2011/08/you-can-list-a-directory-with-8-million-files-but-not-with-ls/
По сути, readdir() читает только 32 КБ записей каталога за раз, и поэтому, если у вас много файлов в каталоге, readdir() займет очень много времени.
Для Python 2.X
import scandir
scandir.walk()
для питона 3.5+
os.scandir()
Я нашел эту библиотеку полезной: https://github.com/benhoyt/scandir.
Кто-то построил модуль Python на основе этой статьи, которая завершает getdents
. Кстати, я знаю, что этот пост старый, но вы можете использоватьscandir
(и я сделал это с каталогами с 21 миллионом файлов). Ходьба - это слишком медленно, хотя это тоже генератор, но слишком много накладных расходов.
Этот модуль кажется интересной альтернативой. Не использовал его, но он основал это на статье LS с 8 миллионами файлов, упомянутой выше. Читая код, думая, что это было бы весело и быстрее использовать.
Также позволяет настраивать буфер, не заходя напрямую в C.
https://github.com/ZipFile/python-getdents И через pip и pypi, хотя я рекомендую прочитать документы.
Я нашел эту библиотеку очень быстро.
https://pypi.org/project/scandir/
Я использовал приведенный ниже код из этой библиотеки, он работал как шарм.
def subdirs(path):
"""Yield directory names not starting with '.' under given path."""
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_dir():
yield entry.name
Вы должны использовать генератор. Эта проблема обсуждается здесь: http://bugs.python.org/issue11406
Я думаю, что использование opendir будет работать, и есть пакет python: http://pypi.python.org/pypi/opendir/0.0.1 который обертывает его через pyrex
http://docs.python.org/release/2.6.5/library/os.html
>>> import os
>>> type(os.walk('/'))
<type 'generator'>