使用 Watch Service API 觀察檔案系統
时间:2014-06-09 21:50:28
收藏:0
阅读:250
在 Java 7 以前,如果要觀察一個目錄下的檔案是否有異動 (新增、修改、刪除),唯一的辦法就是開啟一個 thread,每隔一段時間去檢查一下,當發現有異動,發出異動的訊息。Java 7 提供了 Watch Service API 解決了這個問題,現在不需要再這麼麻煩且浪費系統資源了,透過這組 API 程式可以很優雅、簡單的監控檔案系統的異動狀況。 如下的程式,會監控 D:\temp 這個目錄,如果這個目錄有任何檔案新增、修改、刪除,就會產生 event。
1 package idv.steven.nio2; 2 3 import java.io.IOException; 4 import java.nio.file.FileSystems; 5 import java.nio.file.Path; 6 import java.nio.file.Paths; 7 import java.nio.file.StandardWatchEventKinds; 8 import java.nio.file.WatchEvent; 9 import java.nio.file.WatchKey; 10 import java.nio.file.WatchService; 11 12 public class WatchFile { 13 14 public void run() { 15 final Path path = Paths.get("D:/temp"); 16 WatchService watchService; 17 try { 18 watchService = FileSystems.getDefault().newWatchService(); 19 20 path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, 21 StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE); 22 23 while (true) { 24 final WatchKey key = watchService.take(); 25 26 for (WatchEvent<?> watchEvent : key.pollEvents()) { 27 final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent; 28 final Path filename = watchEventPath.context(); 29 30 System.out.println("kind: " + watchEvent.kind().toString()); 31 System.out.println("filename: " + filename.toString()); 32 } 33 34 break; 35 } 36 37 watchService.close(); 38 System.out.println("exit"); 39 } catch (IOException | InterruptedException e) { 40 e.printStackTrace(); 41 } 42 } 43 44 public static void main(String[] args) { 45 new WatchFile().run(); 46 } 47 }
現在解釋一下程式:
- Line 18: 建立一個檔案系統的監視服務。
- Line 19: 把監視服務註冊到我們要監視的路徑 (D:\temp),並指定要監視的事件類別,這裡指定「新增」、「修改」、「刪除」都要監視。
- Line 24: 程式會停在這一行,開始監視。
- Line 26~34: 監視的目錄有異動,產生的事件在這裡處理,我們很簡單的將事件類別和檔案名稱印出來。
- Line 37: 關閉監視服務。
Line 24 行要特別說明,上述程式呼叫 take() 是方法之一,完整的說明如下:
- poll(): If no key is available, it returns immediately a null value.
- poll(long, TimeUnit): If no key is available, it waits the specified time and tries again. If still no key is available, then it returns null. The time period is indicated as a long number, while the TimeUnit argument determines whether the specified time is minutes, seconds, milliseconds, or some other unit of time.
- take(): If no key is available, it waits until a key is queued or the infinite loop is stopped for any of several different reasons.
评论(0)