你可能會問,爲什麼不用python的watchdog
?因爲watchdog
用戶可重寫的實例方法就那麼幾個:
self.on_any_event(event)
# 任何事件發生都會首先執行該方法,該方法默認爲空,dispatch()方法會先執行該方法,然後再把 event 分派給其他方法處理
self.on_moved(event)
# 處理 DirMovedEvent 和 FileMovedEvent 事件,默認爲空
self.on_created(event)
# 處理 DirCreatedEvent 和 FileCreatedEvent 事件,默認爲空
self.on_deleted(event)
# 處理 DirDeletedEvent 和 FileDeletedEvent 事件,默認爲空
self.on_modified(event)
# 處理 DirModifiedEvent 和 FileModifiedEvent 事件,默認爲空
它無法判斷文件操作是否完成,你需要自己寫其他邏輯來判斷。關於watchdog
在CSDN有篇很詳盡的博文–WatchDog 使用經驗總結,以上事件也轉自那篇博文。
下面我們來說說pyinotify,Pyinotify依賴於Linux內核的功能—inotify(內核2.6.13合併),它支持的事件如下:
@cvar IN_ACCESS: File was accessed.
@type IN_ACCESS: int
@cvar IN_MODIFY: File was modified.
@type IN_MODIFY: int
@cvar IN_ATTRIB: Metadata changed.
@type IN_ATTRIB: int
@cvar IN_CLOSE_WRITE: Writtable file was closed.
@type IN_CLOSE_WRITE: int
@cvar IN_CLOSE_NOWRITE: Unwrittable file closed.
@type IN_CLOSE_NOWRITE: int
@cvar IN_OPEN: File was opened.
@type IN_OPEN: int
@cvar IN_MOVED_FROM: File was moved from X.
@type IN_MOVED_FROM: int
@cvar IN_MOVED_TO: File was moved to Y.
@type IN_MOVED_TO: int
@cvar IN_CREATE: Subfile was created.
@type IN_CREATE: int
@cvar IN_DELETE: Subfile was deleted.
@type IN_DELETE: int
@cvar IN_DELETE_SELF: Self (watched item itself) was deleted.
@type IN_DELETE_SELF: int
@cvar IN_MOVE_SELF: Self (watched item itself) was moved.
@type IN_MOVE_SELF: int
@cvar IN_UNMOUNT: Backing fs was unmounted.
@type IN_UNMOUNT: int
@cvar IN_Q_OVERFLOW: Event queued overflowed.
@type IN_Q_OVERFLOW: int
@cvar IN_IGNORED: File was ignored.
@type IN_IGNORED: int
@cvar IN_ONLYDIR: only watch the path if it is a directory (new
in kernel 2.6.15).
@type IN_ONLYDIR: int
@cvar IN_DONT_FOLLOW: don't follow a symlink (new in kernel 2.6.15).
IN_ONLYDIR we can make sure that we don't watch
the target of symlinks.
@type IN_DONT_FOLLOW: int
@cvar IN_EXCL_UNLINK: Events are not generated for children after they
have been unlinked from the watched directory.
(new in kernel 2.6.36).
@type IN_EXCL_UNLINK: int
@cvar IN_MASK_ADD: add to the mask of an already existing watch (new
in kernel 2.6.14).
@type IN_MASK_ADD: int
@cvar IN_ISDIR: Event occurred against dir.
@type IN_ISDIR: int
@cvar IN_ONESHOT: Only send event once.
@type IN_ONESHOT: int
@cvar ALL_EVENTS: Alias for considering all of the events.
@type ALL_EVENTS: int
如果你需要監控一個文件夾,它定期有文件上傳,上傳完成後需要對最新的文件進行操作,那麼使用pyinotify
的IN_CLOSE_WRITE
事件就非常合適。
使用pyinotify
的方法有如下幾種:
- Using the Notifier class without timeout
The corresponding tutorial file can be found here: tutorial_notifier.py - Using the Notifier class with a timeout
- Using the ThreadedNotifier Class
The corresponding tutorial file can be found here: tutorial_threadednotifier.py. - Using the AsyncNotifier Class
The corresponding tutorial file can be found here: tutorial_asyncnotifier.py. - 由於python3.6之後,asyncore已經被asyncio 取代,所以有了這個詭異的官方例程:pyinotify/asyncio_notifier.py。裏面完全沒寫各種事件怎麼處理,文檔也沒有。
後來一番搜索,終於找到了這個Using pyinotify with python 3 asyncio,代碼如下:
import pyinotify
import asyncio
class EventHandler(pyinotify.ProcessEvent):
def process_IN_CREATE(self, event):
if not event.dir:
print("Got new file: ", event.pathname)
print("Something changed in path: ", event.path)
print("The file changed: ", event.name)
wm = pyinotify.WatchManager() # Watch Manager
mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE # watched events
loop = asyncio.get_event_loop()
notifier = pyinotify.AsyncioNotifier(wm, loop, default_proc_fun=EventHandler())
wdd = wm.add_watch('.', mask, rec=True, auto_add=True)
try:
loop.run_forever()
except:
print('\nshutting down...')
loop.stop()
notifier.stop()
參考文獻: