Как определить количество файлов на диске с помощью Python?
===========================================================

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

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

Любые идеи?

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

Я пишу timemachine-обертку вокруг 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?

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



Правильный ответ для вашей цели состоит в том, чтобы жить без индикатора выполнения один раз, сохранить номер 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, имена файлов) для каждого каталога в файловой системе, начиная с заданного пути.Это, вероятно, займет много времени для `"/"`, но вы уже это знали.

Самый простой способ:

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

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

```

Дайте нам знать, если любой из этих методов работает для вас.

Смотрите также [How do I prevent Python's os.walk from walking across mount points?](https://stackoverflow.com/questions/577761/how-do-i-prevent-pythons-os-walk-from-walking-across-mount-points)



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



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

```
import os 

dirs = 0 
files = 0 

for r, d, f in os.walk('/path/to/drive'): 
    dirs += len(d) 
    files += len(f) 

```