起因
我在开发个人网站 搜网盘(www.souwp.cn) 的时候,需要实现这样一个功能:网站会实时的生成一些新的网页,我需要把这些新增的网页提交给搜索引擎收录。首先想到的是写在生成新网页的代码里面,但是感觉这样耦合性太高,不方便维护。所以想着有没有别的替代方法,就想到了Java7的新特性WatchService 可以实现对目录的监听,然后就可以做同样的事情了。
在实现了 上一步 后,这回接着解决子不能监听子目录下文件变化的问题。
Path targetPath = Paths.get("E:\\temp");
try(WatchService watchService = targetPath.getFileSystem().newWatchService()) {
// 让 targetPath 下的所有文件夹(多层)都注册到 watchService
Files.walkFileTree(targetPath, new SimpleFileVisitor() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
dir.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
return FileVisitResult.CONTINUE;
}
});
WatchKey watchKey = null;
while (true) {
try {
watchKey = watchService.take();
List> watchEvents = watchKey.pollEvents();
for (final WatchEvent> event : watchEvents) {
WatchEvent watchEvent = (WatchEvent) event;
WatchEvent.Kind kind = watchEvent.kind();
Path watchable = ((Path) watchKey.watchable()).resolve(watchEvent.context());
// 在监听到文件夹创建的时候要把这个 path 注册到 watchService 上
if(Files.isDirectory(watchable)){
if(kind == StandardWatchEventKinds.ENTRY_CREATE) {
System.out.println("新建目录 = " + watchable);
watchable.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
}
} else {
if(kind == StandardWatchEventKinds.ENTRY_CREATE) {
System.out.println("新建文件 = " + watchable);
} else if(StandardWatchEventKinds.ENTRY_MODIFY == event.kind()){
System.out.println("修改文件 = " + watchable);
} else if(StandardWatchEventKinds.ENTRY_DELETE == event.kind()){
System.out.println("删除文件 = " + watchable);
}
}
/*if (!watchKey.reset()) {
break;
}*/
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(watchKey != null){
watchKey.reset();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
运行结果:
本文参考 https://blog.csdn.net/qq_31871635/article/details/81164285,并做了适当修改, 感谢作者。