Как определить количество файлов на диске с Python? - PullRequest
5 голосов
/ 22 февраля 2009

Я пытался выяснить, как (быстро) получить количество файлов на данном диске HFS + с помощью python.

Я играл с os.statvfs и тому подобным, но не могу ничего получить (что мне кажется полезным).

Есть идеи?

Редактировать: Позвольте мне быть более конкретным. =]

Я пишу оболочку, похожую на машину времени, по rsync по разным причинам, и хотел бы, чтобы очень быстрая (не обязательно идеальная) оценка числа файлов на диске, который rsync будет сканировать. Таким образом, я могу наблюдать за прогрессом от rsync (если вы называете его как rsync -ax --progress, или с опцией -P), когда он строит свой первоначальный список файлов, и сообщать процент и / или ETA обратно пользователю. *

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

Я пытался поиграть с os.statvfs точно так же, как описано в одном из ответов, но результаты не имеют для меня смысла.

>>> import os
>>> os.statvfs('/').f_files - os.statvfs('/').f_ffree
64171205L

Более портативный способ дает мне около 1,1 миллиона на этой машине, что соответствует показателю, который я видел на этой машине, включая rsync, выполняющую подготовку:

>>> sum(len(filenames) for path, dirnames, filenames in os.walk("/"))
1084224

Обратите внимание, что первый метод является мгновенным, а второй заставил меня вернуться через 15 минут для обновления, потому что это заняло столько времени.

Кто-нибудь знает подобный способ получения этого числа, или что не так с тем, как я трактую / интерпретирую числа os.statvfs?

Ответы [ 4 ]

7 голосов
/ 22 февраля 2009

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

Я не поверил, но это похоже на работу в Linux:

os.statvfs('/').f_files - os.statvfs('/').f_ffree

Это вычисляет общее количество блоков файлов минус свободные блоки файлов. Кажется, он показывает результаты для всей файловой системы, даже если вы указываете ее в другой каталог. os.statvfs реализован только в Unix.

Хорошо, я признаю, что на самом деле я не позволил «медленному, правильному» пути закончиться, прежде чем восхищаться быстрым методом. Всего несколько недостатков: я подозреваю, что .f_files также будет считать каталоги, и результат, вероятно, будет совершенно неверным. Может быть, один раз посчитать файлы медленным способом и скорректировать результат по «быстрому» пути?

Портативный способ:

import os
files = sum(len(filenames) for path, dirnames, filenames in os.walk("/"))

os.walk возвращает 3-кортеж (dirpath, dirnames, filenames) для каждого каталога в файловой системе, начиная с заданного пути. "/" это, вероятно, займет много времени, но вы уже знали это.

Простой способ:

Посмотрим правде в глаза, никто не знает и не заботится о том, сколько у них файлов на самом деле, это смешная статистика. Вы можете добавить эту классную функцию «количество файлов» в вашу программу с помощью этого кода:

import random
num_files = random.randint(69000, 4000000)

Сообщите нам, работает ли какой-либо из этих методов для вас.

См. Также Как предотвратить переход os.walk в Python через точки монтирования?

2 голосов
/ 25 февраля 2009

Вы можете использовать число из предыдущего rsync прогона. Он быстрый, переносимый, и для 10**6 файлов и любой разумной стратегии резервного копирования он даст вам 1% или более высокую точность.

1 голос
/ 23 февраля 2009

Если обход дерева каталогов является опцией (будет медленнее, чем непосредственный запрос к диску):

import os

dirs = 0
files = 0

for r, d, f in os.walk('/path/to/drive'):
  dirs += len(d)
  files += len(f)
0 голосов
/ 22 февраля 2009

Редактировать: Spotlight не отслеживает каждый файл, поэтому его метаданных будет недостаточно.

...