Quiero monitorear una carpeta y ver si se agregan archivos nuevos o si se modifican los archivos existentes. El problema es que no está garantizado que mi programa se ejecute todo el tiempo (por lo tanto, las soluciones basadas en inotify pueden no ser adecuadas aquí). Necesito almacenar en caché el estado del último escaneo y luego con el siguiente escaneo necesito compararlo con el último escaneo antes de procesar los archivos.

¿Cuáles son las alternativas para lograr esto en Python 2.7?

Nota 1: El procesamiento de los archivos es costoso, por lo que estoy tratando de procesar los archivos que no se modifican mientras tanto. Entonces, si solo se cambia el nombre del archivo (a diferencia de un cambio en el contenido del archivo), también me gustaría detectarlo y omitir el procesamiento.

Nota 2: Solo estoy interesado en una solución de Linux, pero no me quejaría si se agregan respuestas para otras plataformas.

0
some user 31 ago. 2014 a las 01:40

4 respuestas

La mejor respuesta

Hay varias formas de detectar cambios en los archivos. Algunos son más fáciles de engañar que otros. No parece que sea un problema de seguridad; más bien se supone buena fe, y solo necesita detectar cambios sin tener que burlar a un adversario.

Puedes mirar las marcas de tiempo. Si los archivos no cambian de nombre, esta es una buena manera para detectar cambios Si cambian de nombre, las marcas de tiempo por sí solas no es suficiente para distinguir de manera confiable un archivo de otro. os.stat te dirá la hora en que se modificó un archivo por última vez.

Puede mirar inodos, por ejemplo, ls -li. El número de inodo de un archivo puede cambiar si los cambios implican crear un nuevo archivo y eliminar el anterior; esto es cómo emacs normalmente cambia los archivos, por ejemplo. Intenta cambiar un archivo con la herramienta estándar que usa su organización, y compare los inodos antes y después; pero tenga en cuenta que incluso si no cambia esta vez, podría cambiar en algunas circunstancias. os.stat te dirá inode números.

Puedes mirar el contenido de los archivos. cksum calcula un pequeño CRC suma de comprobación en un archivo; es fácil de superar si alguien quiere. Programas tales como sha256sum calcula un hash seguro; es inviable cambiar un archivo sin cambiar tal hash. Esto puede ser lento si los archivos son grandes. El módulo hashlib calculará varios tipos de hashes seguros.

Si se cambia el nombre y se cambia un archivo, y su número de inodo cambia, sería potencialmente muy difícil hacer coincidirlo con el archivo que solía ser, a menos que los datos en el archivo contengan algún tipo de identificador inmutable y único.

Piensa en la concurrencia. ¿Es posible que alguien cambie un archivo mientras se ejecuta el programa? Cuidado con las condiciones de carrera.

1
Tom Zych 30 ago. 2014 a las 22:12

Probablemente hubiera optado por algún tipo de solución sqlite, como escribir el último tiempo de votación. Luego, en cada encuesta, ordene los archivos por last_modified_time (mtime) y obtenga todos los que tienen mtime mayor que su encuesta anterior (este valor se eliminará del sqlite o algún tipo de archivo si insiste en no tener un requisito de tal db).

0
amitizle 30 ago. 2014 a las 21:54

Sugiero hacer trampa y usar el sistema comando. Por ejemplo, a continuación se encuentran todos los archivos de Python que se han modificado o creado en los últimos 60 minutos. El uso de la salida ls puede determinar si se necesita más verificación.

$ echo beer > zoot.py
$ find . -name '*.py' -mmin -60 -type f -ls
1973329    4 -rw-r--r--   1 johnm    johnm           5 Aug 30 15:17 ./zoot.py
0
johntellsall 30 ago. 2014 a las 22:21

La supervisión de nuevos archivos no es difícil: solo mantenga una lista o base de datos de inodes para todos los archivos en el directorio. Un nuevo archivo introducirá un nuevo inodo. Esto también lo ayudará a evitar el procesamiento de archivos renombrados, ya que el inodo no cambia al cambiar el nombre.

El problema más difícil es monitorear los cambios de archivos. Si también almacena el tamaño de archivo por inodo, entonces, obviamente, un tamaño modificado indica un archivo modificado y no necesita abrir y procesar el archivo para saberlo. Pero para un archivo que tiene (a) un inodo previamente registrado y (b) tiene el mismo tamaño que antes, necesitará procesar el archivo (por ejemplo, calcular una suma de verificación) para saber si ha cambiado.

1
Chris Johnson 30 ago. 2014 a las 22:10