JAVA 文件監(jiān)控 WatchService的示例方法
概述
java1.7中 提供了WatchService來監(jiān)控系統(tǒng)中文件的變化。該監(jiān)控是基于操作系統(tǒng)的文件系統(tǒng)監(jiān)控器,可以監(jiān)控系統(tǒng)是所有文件的變化,這種監(jiān)控是無需遍歷、無需比較的,是一種基于信號收發(fā)的監(jiān)控,因此效率一定是最高的;現(xiàn)在Java對其進行了包裝,可以直接在Java程序中使用OS的文件系統(tǒng)監(jiān)控器了。
使用場景
- 場景一:比如系統(tǒng)中的配置文件,一般都是系統(tǒng)啟動的時候只加載一次,如果想修改配置文件,還須重啟系統(tǒng)。如果系統(tǒng)想熱加載一般都會定時輪詢對比配置文件是否修改過,如果修改過重新加載。
- 場景二:監(jiān)控磁盤中的文件變化,一般需要把磁盤中的所有文件全部加載一邊,定期輪詢一遍磁盤,跟上次的文件狀態(tài)對比。如果文件、目錄過多,每次遍歷時間都很長,而且還不是實時監(jiān)控。
而以上兩種場景就比較適合使用 WatchService 進行文件監(jiān)控。
示例
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;
public class FileWatchServiceDemo {
public static void main(String[] args) throws IOException, InterruptedException {
WatchService watchService = FileSystems.getDefault().newWatchService();
String filePath = "D:/aa";
Paths.get(filePath).register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
while(true){
WatchKey key = watchService.take();
List<WatchEvent<?>> watchEvents = key.pollEvents();
for (WatchEvent<?> event : watchEvents) {
if(StandardWatchEventKinds.ENTRY_CREATE == event.kind()){
System.out.println("創(chuàng)建:[" + filePath + "/" + event.context() + "]");
}
if(StandardWatchEventKinds.ENTRY_MODIFY == event.kind()){
System.out.println("修改:[" + filePath + "/" + event.context() + "]");
}
if(StandardWatchEventKinds.ENTRY_DELETE == event.kind()){
System.out.println("刪除:[" + filePath + "/" + event.context() + "]");
}
}
key.reset();
}
}
}
1、使用 Path 來指定要監(jiān)控的目錄
2、Path.register() 方法注冊要監(jiān)控指定目錄的那些事件(創(chuàng)建、修改、刪除)
StandardWatchEventKinds.ENTRY_CREATE //創(chuàng)建 StandardWatchEventKinds.ENTRY_MODIFY //修改 StandardWatchEventKinds.ENTRY_DELETE //刪除
3、調(diào)用watchService.take(); 獲取監(jiān)控目錄文件的變化的WatchKey。該方法是阻塞方法,如果沒有文件修改,則一直阻塞。
4、遍歷所有的修改事件,并做相應(yīng)處理。
5、完成一次監(jiān)控就需要重置監(jiān)控器。
不使用 WatchService 監(jiān)控的弊端
- 非常繁瑣,必須自己手動開啟一個后臺線程每隔一段時間遍歷一次目標(biāo)節(jié)點并記錄當(dāng)前狀態(tài),然后和上一次遍歷的狀態(tài)對比,如果不相同就表示發(fā)生了變化,再采取相應(yīng)的操作,這個過程非常長,都需要用戶自己手動實現(xiàn);
- 效率低:效率都消耗在了遍歷、保存狀態(tài)、對比狀態(tài)上了!這是因為舊版本的Java無法很好的利用OS文件系統(tǒng)的功能,因此只能這樣笨拙地監(jiān)控文件變化;
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于javamelody監(jiān)控springboot項目過程詳解
- Java線程池運行狀態(tài)監(jiān)控實現(xiàn)解析
- 基于spring-boot和docker-java實現(xiàn)對docker容器的動態(tài)管理和監(jiān)控功能[附完整源碼下載]
- Java實現(xiàn)實時監(jiān)控目錄下文件變化的方法
- Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)
- Java使用WatchService監(jiān)控文件內(nèi)容變化的示例
- Java實時監(jiān)控日志文件并輸出的方法詳解
- java獲取redis日志信息與動態(tài)監(jiān)控信息的方法
- Java軟件生產(chǎn)監(jiān)控工具Btrace使用方法詳解
相關(guān)文章
基于Springboot+Mybatis對數(shù)據(jù)訪問層進行單元測試的方式分享
本文將介紹一種快高效、可復(fù)用的解決測試方案——對數(shù)據(jù)訪問層做單元測試,文章通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2023-07-07
LeetCode?動態(tài)規(guī)劃之矩陣區(qū)域和詳情
這篇文章主要介紹了LeetCode?動態(tài)規(guī)劃之矩陣區(qū)域和詳情,文章基于Java的相關(guān)資料展開對LeetCode?動態(tài)規(guī)劃的詳細(xì)介紹,需要的小伙伴可以參考一下2022-04-04
Spring中配置ContextLoaderListener方式
這篇文章主要介紹了Spring中配置ContextLoaderListener方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04

