WatchService文件覆盖通知

时间:2018-04-17 20:28:38

标签: java

我希望在文件夹中覆盖文件时收到通知。例如:我在文件夹中有一个A.JSON文件。当我在同一路径中覆盖同一个文件(A.JSON)时,我想收到通知。

我已根据以下链接尝试了WatchService示例。

https://kodejava.org/how-to-monitor-file-or-directory-changes/

    // I kept a file called A.JSON in this path
    Path path = FileSystems.getDefault().getPath("/Users/XYZ/MyProjectWorkspace/MyTestProject/src");

    try {
                    Boolean isFolder = (Boolean) Files.getAttribute(path,
                            "basic:isDirectory", NOFOLLOW_LINKS);
                    if (!isFolder) {
                        throw new IllegalArgumentException("Path: " + path + " is not a folder");
                    }
                } catch (IOException ioe) {
                    // Folder does not exists
                    ioe.printStackTrace();
                }


    System.out.println("Watching path: " + path);
                // We obtain the file system of the Path
                FileSystem fs = path.getFileSystem ();

                // We create the new WatchService using the new try() block
                try(WatchService service = fs.newWatchService()) {

                    // We register the path to the service
                    // We watch for creation events
                    path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);


                    // Start the infinite polling loop
                    WatchKey key = null;
                    while(true) {
                        key = service.take();

                        // Dequeueing events
                        Kind<?> kind = null;
                        for(WatchEvent<?> watchEvent : key.pollEvents()) {

                            /*final Path changed = (Path) watchEvent.context();
                            System.out.println(changed);
                            if (changed.endsWith("A.json")) {
                                System.out.println("My file has changed");
                            }
                            */

                            // Get the type of the event
                            kind = watchEvent.kind();
                            if (OVERFLOW == kind) {
                                continue; //loop
                            } else if (ENTRY_CREATE == kind) {
                                // A new Path was created 
                                //Path newPath = ((WatchEvent<Path>) watchEvent).context();
                                // Output
                                //System.out.println("New path created: " + newPath);
                                System.out.println("New path created");
                            } else if (ENTRY_MODIFY == kind) {
                                // A new Path was created 
                                //Path newPath = ((WatchEvent<Path>) watchEvent).context();
                                // Output
                                //System.out.println("New path created: " + newPath);
                                System.out.println("Modified");
                            }
                        }

                        if(!key.reset()) {
                            break; //loop
                        }
                    }

                } catch(IOException ioe) {
                    ioe.printStackTrace();
                } catch(InterruptedException ie) {
                    ie.printStackTrace();
                }

在新文件夹创建或修改等时有效。但是,我希望在文件夹中覆盖同一文件时收到通知。

请告诉我如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

监视服务仅查找该目录中的更改。如果您在目录中创建一个文件夹,您将被告知该文件夹的创建。如果您在该新文件夹中创建文件,系统可能会通知您已修改监视目录中的文件夹;您不会被告知在监视目录中的文件夹内添加,修改或删除的文件或文件夹。为此,您还需要查看这些子文件夹。

我将if语句替换为以下语句:

if (kind == ENTRY_CREATE || kind == ENTRY_MODIFY || kind == ENTRY_DELETE) {
    Path newPath = ((WatchEvent<Path>) watchEvent).context();
    System.out.println(kind + ": "+newPath+"  ");
}

然后我运行代码,创建,修改和删除&#34; A.json&#34;文件在监视目录中。然后我创建了一个&#34;子文件夹&#34;和&#34;子文件夹&#34;在其中,我创建,修改和删除了#34; A.json&#34;每个。我收到了这个输出:

  

观察路径:/ Users / aneufeld / workspaces / olan / StackOverflow / src / stackoverflow
  ENTRY_CREATE:A.json
  ENTRY_MODIFY:A.json
  ENTRY_DELETE:A.json
  ENTRY_CREATE:子文件夹
  ENTRY_MODIFY:子文件夹
  ENTRY_MODIFY:子文件夹
  ENTRY_MODIFY:子文件夹
  ENTRY_DELETE:子文件夹

如您所见,监视服务仅在监视目录中正确报告创建,修改和删除。当添加或移除文件夹内的条目时,可以将监视目录中的文件夹标记为已修改,但是没有给出关于提供的修改的指示。子子文件夹内的更改完全无声。

要从起始路径中观看所有子文件夹,而不是

path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);

你可以使用:

Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        dir.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
        return FileVisitResult.CONTINUE;
    }
});

这只会注册以path为根的已存在的文件夹。如果创建了新文件夹,您只会收到ENTRY_CREATE个事件。您必须确定该条目是一个目录,然后继续注册它。您可能必须查看ENTRY_DELETE事件,并在删除后从监视服务取消注册路径。锻炼留给学生。