前言
有時候你可能有個疑問,IDE總是可以檢測到外部文件是否發(fā)生了變化怎栽,比如你在某個類里面加了一些代碼丽猬,這時候的IDE就會彈出一個框說你做了更改宿饱。再或者是某個文件夾下的文件發(fā)生了改變,比如新建了一個或者是刪除了一個等等脚祟。這時候我們的IDE依然可以檢測到谬以。這個功能到底是如何實現(xiàn)的呢?這篇文章主要是研究NIO的其中一個類由桌,叫做WatchService
为黎。
也有一些其他的方式可以輕松地實現(xiàn)監(jiān)控文件夾的功能,比如說java輪詢的方式行您,或者是common-io的方式铭乾,我會慢慢比較。
OK娃循,我們直接來看一下簡單例子如何實現(xiàn)炕檩,再去分析如何實現(xiàn)的?
一淮野、代碼實現(xiàn)
1捧书、簡單案例
這個代碼很簡單,只需要四步:
public static void main(String[] args) throws Exception {
//第一步:取得WatchService
WatchService watchService = FileSystems.getDefault().newWatchService();
//第二步:確定要監(jiān)控的路徑
Path path = Paths.get("G:\\");
//第三步:為本路徑綁定WatchService骤星,并確定監(jiān)控的事件
path.register(
watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey key;
//第四步:當(dāng)有事件時经瓷,開始觸發(fā)
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println("事件" + event.kind() + "發(fā)生了,文件是:" + event.context());
}
key.reset();
}
}
這里我們監(jiān)控G盤洞难,然后我們在G盤新建文件舆吮,然后刪除修改,就會在后臺打印相關(guān)信息队贱。
現(xiàn)在就可以監(jiān)控了色冀,很簡單。
2柱嫌、代碼分析
第一步和第二步锋恬,新建一個取得WatchService和取得要監(jiān)控的路徑,這個很容易理解编丘。
第三步綁定与学,這里只需要注意兩件重要的事情:首先,path
將watchService
作為第一個參數(shù)嘉抓,然后是StandardWatchEventKinds的變量參數(shù)索守。一共有四種。
- StandardWatchEventKinds.ENTRY_CREATE—當(dāng)有新文件時觸發(fā)抑片÷逊穑可能是創(chuàng)建了一個新文件。
- StandardWatchEventKinds.ENTRY_MODIFY—當(dāng)文件被修改時觸發(fā)。所有的文件編輯都會觸發(fā)這個事件截汪。在一些平臺上疾牲,甚至改變文件屬性也會觸發(fā)它。
- StandardWatchEventKinds.ENTRY_DELETE—當(dāng)文件被刪除挫鸽、移動或重命名時觸發(fā)说敏。
- StandardWatchEventKinds.OVERFLOW—觸發(fā)表示丟失或丟棄的事件。
第四步不斷監(jiān)控丢郊,當(dāng)watchService里面不為空時盔沫,開始獲取相應(yīng)的事件,并poll彈出枫匾。最后還有一個reset 表示回退到相應(yīng)的句柄架诞,繼續(xù)處理下一次事件。
3干茉、源碼分析
由于watchService是一個接口谴忧,所以分析起來也比較簡單。里面一共包含了三個方法
//方法1:關(guān)閉watchService
@Override
void close() throws IOException;
//方法2:彈出事件
WatchKey poll();
//方法3:帶有參數(shù)的彈出
WatchKey poll(long timeout, TimeUnit unit)
throws InterruptedException;
//方法4:獲取事件角虫。
WatchKey take() throws InterruptedException;
由于方法比較簡單沾谓,所以我們可以直接看方法上的注釋就可以了。
結(jié)論
WatchService接口是在java7
的版本中引入的戳鹅。主要是處理NIO的文件相關(guān)問題均驶。但是WatchService其實是有很多缺點的。
- WatchService是采用掃描式的枫虏,效率低妇穴。
- WatchService代碼寫起來費勁。雖然上面看起來很簡潔了隶债,但是實際開發(fā)時麻煩腾它。
- WatchService不能監(jiān)聽到多級目錄,事先父文件夾需要存在死讹。
鑒于以上原因瞒滴,在簡單的實現(xiàn)時,可以使用赞警,但是還有一個更強大的工具commons-io
逛腿,使用更簡單也更加的高效。下篇文章給出仅颇。