¿Cómo se determina el número de archivos en una unidad con Python?


5

He estado tratando de encontrar la forma de recuperar (rápidamente) la cantidad de archivos en una unidad HFS + dada con python.

He estado jugando con os.statvfs y tal, pero no puedo conseguir nada (eso me parece útil).

¿Alguna idea?

Editar: Déjame un poquito más específico. =]

Estoy escribiendo un contenedor tipo timemachine alrededor de rsync por varias razones, y me gustaría obtener una estimación muy rápida (no tiene que ser perfecta) de la cantidad de archivos en la unidad que rsync va a escanear. De esta forma puedo ver el progreso desde rsync (si lo llamas como rsync -ax --progress, o con la opción -P) a medida que construye su lista de archivos inicial, e informa un porcentaje y/o ETA de vuelta al usuario.

Esto está completamente separado de la copia de seguridad real, lo cual no es problema para seguir el progreso. Pero con las unidades en las que estoy trabajando con varios millones de archivos, significa que el usuario está mirando un contador de la cantidad de archivos que suben sin límite superior durante unos minutos.

He intentado jugar con os.statvfs exactamente con el método descrito en una de las respuestas hasta ahora, pero los resultados no tienen sentido para mí.

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

La forma más portátil a mi alrededor de 1,1 millones da en esta máquina, que es el mismo que cualquier otro indicador que he visto en esta máquina, incluyendo rsync funcionando sus preparativos:

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

Tenga en cuenta que el primer método es instantáneo, mientras que el segundo me hizo volver 15 minutos después para actualizar porque tardó tanto tiempo en ejecutarse.

¿Alguien sabe de una manera similar de obtener este número, o qué hay de malo en cómo estoy tratando/interpretando los números de os.statvfs?

  0

¿Cómo varía la salida de os.statvfs [os.B_FILES] de lo esperado? (Si pudiera pegar resultados de muestra de os.statvfs y explicar * por qué * no es útil, eso ayudaría a las personas que no conocen OS X a que lo ayuden). 22 feb. 092009-02-22 03:54:25

  0

@Charles: He actualizado mi pregunta con algunos detalles reales ahora ... 24 feb. 092009-02-24 17:08:29

  0

Puede usar un número de una ejecución de rsync anterior. Es rápido, portátil, y para archivos 10 ** 6 y cualquier estrategia de respaldo razonable, le dará una precisión del 1% o superior. 24 feb. 092009-02-24 18:25:49

  0

@ J.F .: ¡Muy bien! Deberías publicar eso como una respuesta real para que pueda darle un +1. 24 feb. 092009-02-24 21:17:32

2

Se puede usar un número de un rsync ejecución anterior. Es rápido, portátil, y para los archivos 10**6 y cualquier estrategia de respaldo razonable, le dará 1% o una mejor precisión.

  0

@Sebastian: Publicaste esto en el comentario mucho antes que joeforker, así que obtienes la marca de verificación de mi parte. 26 feb. 092009-02-26 18:27:55


7

La respuesta correcta para su propósito es vivir sin una barra de progreso una vez, almacenar el número que se le ocurrió a rsync y asumir que tiene la misma cantidad de archivos que la última vez para cada copia de seguridad sucesiva.

yo no lo creía, pero esto parece que funciona en Linux:

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

Este calcula el número total de bloques de archivos menos los bloques de archivo libres. Parece mostrar resultados para todo el sistema de archivos, incluso si lo apunta a otro directorio. os.statvfs está implementado solo en Unix.

OK, lo admito, no dejé que la forma 'lenta y correcta' terminara antes de maravillarme con el método rápido. Solo algunos inconvenientes: sospecho que .f_files también contará directorios, y el resultado probablemente sea totalmente incorrecto. ¿Podría funcionar contar los archivos por el camino lento, una vez, y ajustar el resultado de la manera "rápida"?

La forma portátil:

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

os.walk devuelve un 3-tupla (dirpath, dirnames, nombres de archivos) para cada directorio en el sistema de ficheros a partir de la ruta dada.Esto probablemente demorará mucho tiempo en "/", pero ya lo sabía.

La forma más fácil:

Seamos realistas, nadie sabe o le importa la cantidad de archivos que realmente tienen, es una estadística monótona y sin objeto. Puede añadir este 'número de archivos' fresco característica a su programa con este código:

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

hacernos saber si cualquiera de estos métodos funciona para usted.

Ver también How do I prevent Python's os.walk from walking across mount points?

  0

Esto es exactamente lo que estaba intentando por adelantado, pero el número resultante no tiene sentido para mí. He editado la pregunta anterior para ser más específico. 24 feb. 092009-02-24 17:09:01

  0

jaja, amo el humor en el comentario al azar. 31 oct. 092009-10-31 01:56:43


0

Editar: Spotlight no hace un seguimiento de todos los archivos, por lo que no será suficiente sus metadatos.

  0

Estoy bastante seguro de que el foco no recorre todo tu volumen. Creo que se adhiere a/Aplicaciones y/Usuarios (e ignora cosas como ~/Biblioteca). 23 feb. 092009-02-23 01:09:29


1

Si recorrer el árbol de directorios es una opción (sería más lenta que la consulta de la unidad directamente):

import os 

dirs = 0 
files = 0 

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