使用Java监视服务监视子文件夹

我正在使用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 watchEvent = castEvent(event); System.out.println(event.kind().name().toString() + " " + _directotyToWatch.resolve(watchEvent.context())); watchKey.reset(); } } 

它对我来说很好。 如果我修改raja文件夹中的文件,它会给我带路径的文件名。 但是,当我将一些文件放在像“E:/ Raja / Test”这样的子文件夹中时,它只给出了我放置它的路径,而不是文件名。

如何获取文件名?

你没有在子文件夹中创建/修改文件名的原因由Stephen C在他的回答中给出 。

下面是一个简单的示例, 说明如何注册目录子目录以查看您感兴趣的事件:

 /** * 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() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); return FileVisitResult.CONTINUE; } }); } 

查看官方Java教程:查看目录以进行更改 。 在那里你可以找到非常好的解释和源代码示例。

特别是您将对如何观察目录(或目录树 )以更改文件的示例感兴趣: WatchDir 。

我在上面提供的方法取自这个例子(为简洁省略了一些部分)。
阅读教程了解详细信息。

您只看到“E:/ Raja / Test”而不是“E:/Raja/Test/Foo.txt”(例如)的事件的原因是您只注册了“E:/ Raja”目录与服务。 这意味着您将在目录及其直接成员上看到事件。 “E:/ Raja / Test”是该目录的成员,您正在获取事件,说明已经更改…添加文件时。

解决方案是注册“E:/ Raja”的所有子目录……沿着你需要的目录层次结构向下走。

我知道这很难看,希望有人有更好的答案,但你可以:

解决方案1:

创建每个子文件夹中每个文件的列表,并在上次修改时间。

当您收到ENTRY_CREATE或ENTRY_DELETE时,将该文件夹与列表进行比较,以确定更改了哪个文件

当您收到ENTRY_MODIFY时,比较上次修改时间。

请记住更新您的列表。

编辑:作为一个消化,C#更好地处理文件观察者的事情