问:如何使用快速实现Java文件变更监听?
答:WatchService接口。WatchService是JDK 7提供的接口,其实现了Closeable,可采用try...with方式关闭。
注:WatchService监听的是目录,而不是某个文件为基准。
示例代码:
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.Objects;
public static void main(String[] args) {
final String fileName = "testText.txt";
final String filePath = "C:\\Users\\admin\\Desktop\\testText.txt";
File file = new File(filePath);
String parent = file.getParent();
System.out.println(parent); // 获取到的是目录
// 注册监听服务
WatchService watchService;
try {
watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(parent);
WatchKey wk = path.register(watchService,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE);
System.out.println(wk); // 只做断点看看
} catch (IOException e) {
e.printStackTrace();
return;
}
// 监听修改线程:目录下的所有监听项都会在这里响应,所以要根据文件名来区分
Thread wThread = new Thread(() -> {
while (true) {
try {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> pollEvent : watchKey.pollEvents()) {
String eventName = pollEvent.context().toString();
System.out.println(eventName);
if (Objects.equals(eventName, fileName)) {
System.out.println("检测到变更");
// TODO 此处进行重新读取文件并处理,coding。。。
break;
}
}
watchKey.reset(); // 必须重置监视Key
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// wThread.setDaemon(true); // 守护进程
wThread.start();
// 注册关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
watchService.close();
System.out.println("文件监听钩子已关闭");
} catch (IOException e) {
e.printStackTrace();
}
}));
}
本文参考:京东张开涛老师《亿级流量网站架构核心技术》