WatchService介绍
1、 该类的对象就是操作系统原生的文件系统监控器!我们都知道OS自己的文件系统监控器可以监控系统上所有文件的变化,这种监控是无需遍历、无需比较的,是一种基于信号收发的监控,因此效率一定是最高的;现在Java对其进行了包装,可以直接在Java程序 中使用OS的文件系统监控器了;
2、 获取当前OS平台下的文件系统监控器:
i. WatchService watcher = FileSystems.getDefault().newWatchService();
ii. 从FileSystems这个类名就可以看出这肯定是属于OS平台文件系统的,接下来可以看出这一连串方法直接可以得到一个文件监控器;
WatchService使用
@Slf4j
public class DirectoryTargetMonitor {
//文件监听器,通过操作系统原生文件系统来运行
private WatchService watchService;
//监听路径
private final Path path;
private volatile boolean start = false;
public DirectoryTargetMonitor(String targetPath) {
this.path = Paths.get(targetPath);
}
public void startMonitor() throws Exception {
//watchService实例化
this.watchService = FileSystems.getDefault().newWatchService();
//监控文件的 修改 增加 删除
this.path.register(watchService,StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,StandardWatchEventKinds.ENTRY_MODIFY);
this.start =true;
while (start){
WatchKey watchKey = null;
try {
log.info("开始监控");
//获取变化信息的监控池,没有则一直阻塞
watchKey = watchService.take();
//获取事件列表
List<WatchEvent<?>> watchEvents = watchKey.pollEvents();
log.info("获取事件");
for (WatchEvent<?> watchEvent : watchEvents) {
//监听事件类型
WatchEvent.Kind<?> kind = watchEvent.kind();
//得到监听文件的路径(文件名)
Path name =(Path) watchEvent.context();
//获取全路径 path + name
Path allPath = this.path.resolve(name);
log.info("{}:{}:{}",kind,allPath,name);
}
} catch (Exception e) {
System.out.println("被打断");
e.printStackTrace();
this.start =false;
} finally {
//每次得到新事件后,都需要重置
if (watchKey != null) watchKey.reset();
}
}
}
public void stopMonitor() throws Exception {
log.info("目录 {} 将要关闭监听",path);
this.start = false;
this.watchService.close();
log.info("目录 {} 已经关闭监听",path);
}
}