通过pyinotify实现文件的监控,包括监控文件是否传输完成
首先安裝pyinofity,pip install pyinotify
創建Event Processor
與linux下面的inotify事件機制類似,我們通過繼承ProcessEvent來實現對inotify事件的重寫,這里將事件名封裝成process_事件名,例如IN_CREATE會經過Event Processor變成process_IN_CREATE。下面是所有的事件:
| IN_CREATE | File/directory created in watched directory |
| IN_OPEN | File/directory opened in watched directory |
| IN_ACCESS | File accessed |
| IN_ATTRIB | Attributes of file/directory changed (e.g. permissions, timestamp, etc.) |
| IN_CLOSE_NOWRITE | Non-writable file/directory closed |
| IN_DELETE | File/directory deleted from watched directory |
| IN_DELETE_SELF | File/directory being watched deleted |
| IN_IGNORED | File/directory no longer watched, deleted, or unmounted filesystem |
| IN_MODIFY | File/directory modified |
| IN_MOVE_SELF | File/directory moved. Must monitor destination to know destination path |
| IN_MOVED_FROM | File/directory moved from one watched directory to another |
| IN_MOVED_TO | Similar to IN_MOVED_FROM except for outgoing file/directory |
| IN_Q_OVERFLOW | Event queue overflowed |
| IN_UNMOUNT | Filesystem of watched file/directory unmounted from system |
下面將通過一個簡短的例子來展示:
import os import pyinotifyclass EventProcessor(pyinotify.ProcessEvent):_methods = ["IN_CREATE","IN_OPEN","IN_ACCESS","IN_ATTRIB","IN_CLOSE_NOWRITE","IN_CLOSE_WRITE","IN_DELETE","IN_DELETE_SELF","IN_IGNORED","IN_MODIFY","IN_MOVE_SELF","IN_MOVED_FROM","IN_MOVED_TO","IN_Q_OVERFLOW","IN_UNMOUNT","default"]def process_generator(cls, method):def _method_name(self, event):print("Method name: process_{}()\n""Path name: {}\n""Event Name: {}\n".format(method, event.pathname, event.maskname))_method_name.__name__ = "process_{}".format(method)setattr(cls, _method_name.__name__, _method_name)for method in EventProcessor._methods:process_generator(EventProcessor, method)watch_manager = pyinotify.WatchManager() event_notifier = pyinotify.Notifier(watch_manager, EventProcessor())watch_this = os.path.abspath("/home/vincent/software") watch_manager.add_watch(watch_this, pyinotify.ALL_EVENTS) event_notifier.loop()這里我們可以看到,監控了一個文件夾/home/vincent/software,當往這個文件夾中復制一份文件時,將會打印出所有對應的事件。
Method name: process_IN_CREATE() Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh Event Name: IN_CREATEMethod name: process_IN_OPEN() Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh Event Name: IN_OPENMethod name: process_IN_MODIFY() Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh Event Name: IN_MODIFYMethod name: process_IN_MODIFY() Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh Event Name: IN_MODIFYMethod name: process_IN_MODIFY() Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh Event Name: IN_MODIFYMethod name: process_IN_CLOSE_WRITE() Path name: /home/vincent/software/Anaconda3-2021.05-Linux-x86_64.sh Event Name: IN_CLOSE_WRITE可以看出來,他會記錄下文件操作的每一步,包括文件創建IN_CREATE,文件打開IN_OPEN,文件修改IN_MODIFY,文件關閉IN_CLOSE_WRITE
Non-Blocking Loop非阻塞方式
上面的loop()的方式會阻塞進程,在loop后面的代碼將不會被執行,這里有三種解決辦法:
Notifier with a timeout 使用超時
在構造notifier時,timeout參數告訴Notifier以特定的時間間隔獲取通知。
event_notifier = pyinotify.Notifier(watch_manager, EventProcessor(), timeout=10)當使用超時時,應用程序將不會自動獲得文件系統更改通知。需要在不同的時間顯式調用event_notifier.process_events()和event_notifier.read_events()。也可以調用event_notifier.check_events()來檢查是否有事件等待處理。
ThreadedNotifier不同線程
可以將程序放到另一個線程中,通過ThreadedNotifier而不是Notifier調用,然后通過event_notifier.start()啟動
event_notifier = pyinotify.ThreadedNotifier(watch_manager, EventProcessor())watch_this = os.path.abspath("notification_dir") watch_manager.add_watch(watch_this, pyinotify.ALL_EVENTS) event_notifier.start()AsyncNotifier異步
可以通過異步實現:
event_notifier = pyinotify.AsyncNotifier(watch_manager, EventProcessor())然后通過調用asyncore中的loop()函數實現:
import asyncore asyncore.loop()inotify的局限性也適用于pyinotify。例如,不監視遞歸目錄;必須運行另一個inotify實例來跟蹤子目錄。盡管Python提供了一個方便的inotify接口,但與C實現的inotify相比,會導致性能下降。
總結
以上是生活随笔為你收集整理的通过pyinotify实现文件的监控,包括监控文件是否传输完成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Emotn浏览器TV版如何收藏网页
- 下一篇: 什么样的精子是正常的