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

时间:2013-05-17 14:22:51

标签: java watchservice

我正在使用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”这样的子文件夹中时,它只给出了我放置它的路径,而不是文件名。

如何获取文件名?

3 个答案:

答案 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)

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

解决方案1:

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

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

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

请务必更新您的列表。

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