7 votes

Utilisation de pyinotify pour surveiller la création d'un fichier, mais attendre qu'il soit complètement écrit sur le disque

J'utilise pyinotify pour surveiller la création de fichiers dans un dossier. Et lorsque certains fichiers sont créés, je veux les déplacer. Le problème est que dès que le fichier est créé (évidemment), mon programme essaie de le déplacer, avant même qu'il ne soit complètement écrit sur le disque.

Existe-t-il un moyen de faire en sorte que pyinotify attende qu'un fichier soit complètement écrit sur le disque avant de me notifier qu'il a été créé ? Ou y a-t-il un moyen simple de faire en sorte que, après avoir été notifié, python attende pour le déplacer qu'il ait fini d'être écrit ?

15voto

unutbu Points 222216

Faire réagir pyinotify à IN_CLOSE_WRITE événements :

wm.add_watch(watched_dir, pyinotify.IN_CLOSE_WRITE, proc_fun=MyProcessEvent())

Il s'agit de man 5 incrontab mais il s'applique tout aussi bien à pyinotify :

   IN_ACCESS           File was accessed (read) (*)
   IN_ATTRIB           Metadata changed (permissions, timestamps, extended attributes, etc.) (*)
   IN_CLOSE_WRITE      File opened for writing was closed (*)
   IN_CLOSE_NOWRITE    File not opened for writing was closed (*)
   IN_CREATE           File/directory created in watched directory (*)
   IN_DELETE           File/directory deleted from watched directory (*)
   IN_DELETE_SELF           Watched file/directory was itself deleted
   IN_MODIFY           File was modified (*)
   IN_MOVE_SELF        Watched file/directory was itself moved
   IN_MOVED_FROM       File moved out of watched directory (*)
   IN_MOVED_TO         File moved into watched directory (*)
   IN_OPEN             File was opened (*)

1voto

pyfunc Points 31088

Il est assez difficile de savoir à ce niveau si un fichier est en cours d'écriture. Ce que vous pouvez faire, c'est tester si un fichier est ouvert par un autre processus.

1) Parmi les différents drapeaux utilisés lors de l'ouverture d'un fichier, le drapeau O_EXLOCK pourrait être utile. Si l'indicateur O_EXLOCK est activé, le descripteur de fichier dispose d'un verrou exclusif sur le fichier. Donc, si vous pouvez faire os.open() avec l'indicateur O_EXLOCK, c'est que le fichier n'est pas ouvert par d'autres processus. Cela devrait fonctionner sur tous les systèmes d'exploitation compatibles avec posix, mais je ne l'ai pas testé. Si le fichier est ouvert, vous pouvez le fermer, attendre et réessayer.

2) Vous pouvez également essayer os.stat et voir le changement d'horodatage et essayer d'interpréter les informations en toute sécurité. Bien que cette méthode ne soit pas infaillible.

3) Sur les systèmes Unix, vous pouvez essayer "lsof"

4) La page suivante décrit l'utilisation de liens symboliques à partir de /proc/PID/fd pour tester les fichiers ouverts.

[Edit : Liens mis à jour]

1voto

gnibbler Points 103484

Si vous contrôlez le processus d'écriture, vous pouvez appeler le fichier "foo.part" pendant qu'il est en cours d'écriture et le renommer "foo" lorsqu'il est fermé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X