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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16611426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:27:43  来源:igfitidea点击:

Monitor subfolders with a Java watch service

javawatchservice

提问by Raja

I am using watchKeyto listen for a file change in a particular folder.

我正在使用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();
    }
}


It working fine for me. If I modify a file in raja folder it gives me the file name with path. But, when I put some files in subfolders like "E:/Raja/Test", it gives me only the path where I put it, not the file name.


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

How to get the file name?

如何获取文件名?

回答by informatik01

The reason whyyou're not getting the file name created/modified inside a subfolder is given by Stephen Cin his answer.

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

Here is a simple example of howto register directoriesand subdirectoriesto watch them for the events you are interested in:

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

/**
 * 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;
        }

    });

}


Check out the official Java Tutorials: Watching a Directory for Changes. There you can find very nice explanations and examples with the source code.

查看官方 Java 教程:观察目录的变化。在那里您可以找到非常好的解释和示例以及源代码。

Particularly you'll be interested in this example of how to watch a directory (or directory tree) for changes to files: WatchDir.java.

特别是您会对这个关于如何观察目录(或目录树)的文件更改的示例感兴趣:WatchDir.java

The method I supplied above was taken from this example (omitting some parts for brevity).
Read the tutorial for the details.

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

回答by Stephen C

The reason you are only seeing an event for "E:/Raja/Test" and not "E:/Raja/Test/Foo.txt" (for example) is that you've only registered the "E:/Raja" directory with the service. This means you will see events on the directory and its immediate members. The "E:/Raja/Test" is a member of the directory, and you are getting events to say that is has been changed ... when files are added to it.

您只看到“E:/Raja/Test”事件而不是“E:/Raja/Test/Foo.txt”(例如)的原因是您只注册了“E:/Raja”目录与服务。这意味着您将看到有关目录及其直接成员的事件。"E:/Raja/Test" 是该目录的一个成员,当文件被添加到它时,你会收到事件说它已经改变了。

The solution is to register all of subdirectories of "E:/Raja" as well ... going as far down the directory hierarchy as you need to go.

解决方案是同时注册“E:/Raja”的所有子目录……在您需要的目录层次结构中尽可能向下。

回答by Nick

I know this is ugly, hopefully somebody has a better answer but you can create a list of every file in every subfolder and there last modified times.

我知道这很难看,希望有人有更好的答案,但您可以创建每个子文件夹中每个文件的列表,并列出最后修改时间。

When you receive ENTRY_CREATE or ENTRY_DELETE compare the folder to your list to figure out which file was changed

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

When you receive a ENTRY_MODIFY compare the last modified times.

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

Remember to update your list.

记得更新你的清单。