Java 1.6版本之前是不存在目錄監控的API的。若是要實現這種功能必需要本身遍歷目錄,記錄各個文件的狀況,而後定時所有遍歷一次,從 JDK7 以後出現了 WatchService
類,實現了對目錄下文件的監控。java
整個監控目錄文件操做的流程大體以下:操作系統
WatchService
類的實現其實是對操做系統的文件監視器的封裝,相比以前的手動實現,優雅了很多。由於不須要遍歷文件總體而言效率也高不少。如下爲獲取 WatchService
實例的代碼,經過 FileSystem.getDefault() 可看出並不是是本身實現的。從 newWatchService()
方法名看, WatchService
能夠獲取多個。.net
WatchService watchService = FileSystems.getDefault().newWatchService();
實際上調用此方法後,程序會新開一個線程,監視文件變化發出的信號,此時線程還沒有就緒。線程
有了監視器,接下來咱們須要註冊監視器了。code
Path path = Paths.get("src"); WatchKey watchKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
註冊監視器須要用到 Path
實例,該實例對應的必須是一個目錄,不容許是一個文件。
方法比較簡單,就是說爲目錄註冊一個監視器,監視目錄下文件的變化。
關於 StandardWatchEventKinds.ENTRY_MODIFY
,表示監視文件的修改事件,它是 WatchEvent.Kind<?>
的實現類。
看起來它像是枚舉,實際上它並非。JDK 中幫咱們定義了三種事件,新增、修改和刪除。orm
獲取目錄的變化須要使用 WatchService
的 take()
方法或 poll()
方法。對象
WatchKey key = watchService.take(); WatchKey pollKey = watchService.poll();
take()
是一個阻塞方法,會等待監視器發出的信號才返回。poll()
是一個非阻塞方法,會當即返回當時監視器中是否有信號。
返回的 WatchKey
對象,其實是一個單例,和以前 path.register()
方法返回的實例是同一個。它只能保存某一時間點的文件變化信息。blog
List<WatchEvent<?>> events = key.pollEvents(); for (WatchEvent<?> pollEvent : events) { Object o = pollEvent.context(); WatchEvent.Kind kind = pollEvent.kind(); } key.reset();
pollEvents()
用於獲取文件變化事件,只能獲取一次,不能重複獲取,相似隊列的形式。context()
返回觸發該事件的那個文件或目錄的路徑(相對路徑)kind()
返回事件類型(ENTRY_CREATE、ENTRY_DELETE、ENTRY_MODIFY之一)reset()
每次調用 WatchService 的 take() 或 poll() 方法時須要經過本方法重置。隊列
public void watchServiceExample() throws IOException, InterruptedException { WatchService watchService = FileSystems.getDefault().newWatchService(); Path path = Paths.get("D:/code"); WatchKey watchKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); while (true) { // 嘗試獲取下一個變化信息的監控池,若是沒有變化則一直等待 WatchKey key = watchService.take(); for (WatchEvent<?> pollEvent : key.pollEvents()) { System.out.println(String.format("%s is %s.", pollEvent.context().toString(), pollEvent.kind().name().substring(6))); } if (!key.reset()) { break; } } }
WatchService 的優勢就不用多說了,這裏就說一個缺點: 只能監視當前目錄下的文件和目錄,不能監視子目錄 。事件
參考
[瘋狂Java]NIO.2:WatchService、WatchKey(監控文件變化)
本文若有問題,歡迎在評論區中指正。