我正在使用watchKey
来监听特定文件夹中的文件更改。
Path _directotyToWatch = Paths.get("E:/Raja");
WatchService watcherSvc = FileSystems.getDefault().newWatchService();
WatchKey watchKey = _directotyToWatch.register(watcherSvc, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
while (true) {
watchKey=watcherSvc.take();
for (WatchEvent<?> event: watchKey.pollEvents()) {
WatchEvent<Path> watchEvent = castEvent(event);
System.out.println(event.kind().name().toString() + " " + _directotyToWatch.resolve(watchEvent.context()));
watchKey.reset();
}
}
它对我来说很好。如果我修改raja文件夹中的文件,它会给我带路径的文件名。但是,当我将一些文件放在像“E:/ Raja / Test”这样的子文件夹中时,它只给出了我放置它的路径,而不是文件名。
如何获取文件名?
答案 0 :(得分:15)
为什么你没有在子文件夹中创建/修改文件名的原因由 Stephen C 在他的answer中提供。
以下是如何注册目录和子目录以查看您感兴趣的事件的简单示例:
/**
* Register the given directory, and all its sub-directories, with the WatchService.
*/
private void registerAll(final Path start) throws IOException {
// register directory and sub-directories
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
return FileVisitResult.CONTINUE;
}
});
}
查看官方Java教程:Watching a Directory for Changes。在那里你可以找到非常好的解释和源代码示例。
特别是您会对如何观看目录(或目录树)以更改文件的示例感兴趣:WatchDir。
我上面提供的方法来自这个例子(为简洁省略了一些部分) 阅读教程了解详细信息。
答案 1 :(得分:9)
您只看到“E:/ Raja / Test”而不是“E:/Raja/Test/Foo.txt”(例如)的事件的原因是您只注册了“E:/ Raja“服务目录。这意味着您将在目录及其直接成员上看到事件。 “E:/ Raja / Test”是该目录的成员,您正在获取事件,说明已经更改...添加文件时。
解决方案是注册“E:/ Raja”的所有子目录......在你需要的目录层次结构中尽可能远。
答案 2 :(得分:0)
我知道这很难看,希望有人有更好的答案,但你可以:
创建每个子文件夹中每个文件的列表,并在上次修改时间。
当您收到ENTRY_CREATE或ENTRY_DELETE时,将该文件夹与列表进行比较以确定哪个文件已更改
当您收到ENTRY_MODIFY时,比较上次修改时间。
请务必更新您的列表。
编辑: 作为一个消化,C#更好地处理文件观察者的事情