很多時(shí)候,我們需要及時(shí)對文件系統(tǒng)(file sytem)的變化進(jìn)行監(jiān)控,以便第一時(shí)間 增量處理。Python 在這方面提供兩個(gè)非常優(yōu)秀的第三方開源工具:watchdog 和 pyinotify ,背后都是依賴 Linux 系統(tǒng)的 inotify 庫。 inotify 是一個(gè)Linux系統(tǒng)的特性,用于監(jiān)控文件系統(tǒng)操作,比如:讀取、寫入和創(chuàng)建,比頻繁的輪詢要高效很多。
當(dāng)然,監(jiān)控文件系統(tǒng)時(shí),我們可以輪詢的方式,但這樣效果非常低,極不優(yōu)雅。所以,強(qiáng)烈建議使用 watchdog 或 pyinotify 。 通過對比,不難發(fā)現(xiàn) watchdog 大有取代 pyinotify 之勢。所以,新項(xiàng)目就最好直接使用 watchdog ,但舊項(xiàng)目就沒有必要替換掉 pyinotify 了。 watchdog通過 pip install watchdog 安裝之后,我們就可以在 Python 代碼中直接使用 watchdog ,十分方便??梢宰约簩?shí)現(xiàn)監(jiān)控的回調(diào)函數(shù),或直接用已經(jīng)提供好的函數(shù)。 import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
# 配置日志模塊
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
# 定義監(jiān)控目錄的參數(shù)
path = sys.argv[1] if len(sys.argv) > 1 else '.'
# 日志事件句柄,實(shí)現(xiàn)了日志記錄功能,也可以自己定義Handler
event_handler = LoggingEventHandler()
observer = Observer()
# 定義監(jiān)控
observer.schedule(event_handler, path, recursive=True)
# 啟動(dòng)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
LoggingEventHandler 的實(shí)現(xiàn)代碼如下:
class LoggingEventHandler(FileSystemEventHandler):
"""Logs all the events captured."""
def on_moved(self, event):
super(LoggingEventHandler, self).on_moved(event)
what = 'directory' if event.is_directory else 'file'
logging.info("Moved %s: from %s to %s", what, event.src_path,
event.dest_path)
def on_created(self, event):
super(LoggingEventHandler, self).on_created(event)
what = 'directory' if event.is_directory else 'file'
logging.info("Created %s: %s", what, event.src_path)
def on_deleted(self, event):
super(LoggingEventHandler, self).on_deleted(event)
what = 'directory' if event.is_directory else 'file'
logging.info("Deleted %s: %s", what, event.src_path)
def on_modified(self, event):
super(LoggingEventHandler, self).on_modified(event)
what = 'directory' if event.is_directory else 'file'
logging.info("Modified %s: %s", what, event.src_path)
我們就可以照葫蘆畫瓢了,實(shí)現(xiàn)自己想要的回調(diào)函數(shù),官方的文檔 的質(zhì)量不是特別高,有些內(nèi)容需要我們閱讀源碼,還好源碼不是很復(fù)雜。 pyinotifypyinotify 已經(jīng)是老牌的文件系統(tǒng)監(jiān)控的庫了,已經(jīng)比較穩(wěn)定了,功能方面也滿足需求。
也是可以通過 pip install pyinotify 進(jìn)行安裝。 import pyinotify
wm = pyinotify.WatchManager()
# 定義監(jiān)控事件,刪除和創(chuàng)建
mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE
# 返回的對象,方便之后的管理,比如:刪除等
wdd = wm.add_watch('/tmp', mask, rec=True)
# 定義回調(diào)函數(shù)
class EventHandler(pyinotify.ProcessEvent):
def process_IN_CREATE(self, event):
print "Creating:", event.pathname
def process_IN_DELETE(self, event):
print "Removing:", event.pathname
handler = EventHandler()
# 將回調(diào)函數(shù)和監(jiān)控組合
notifier = pyinotify.Notifier(wm, handler)
# 循環(huán)監(jiān)控
notifier.loop()
相比 watchdog 的 API,pyinotify 的 API 稍微繁瑣了一點(diǎn)點(diǎn),整體上不分伯仲。pyinotify 的文檔方面要強(qiáng)于 watchdog ,有大量的細(xì)節(jié)講解。 總結(jié)watchdog 目前還在持續(xù)更新,熱度也很高,所以相比 pyinotify 已經(jīng)很長時(shí)間不更新了,watchdog 的使用前景更可期待,API 的風(fēng)格更符合現(xiàn)在的代碼設(shè)計(jì),推薦使用 watchdog 。
最后,安利大家一本書《深入理解NLP的中文分詞:從原理到實(shí)踐》,讓你從零掌握中文分詞技術(shù),踏入NLP的大門。
|