当新文件添加到监视文件夹时,Java NIO 监视服务创建了 'ENTRY_CREATE' 和 'ENTRY_MODIFY'

标签 java nio watchservice

I see a strange behaviour ( not sure i this is expected behaviour ) using java.nio.file.WatchService.

问题是我有一个用 WatchService 注册的文件夹。 当我将一个新文件复制到此文件夹中时,会生成两个 WatchEvent,每个用于:

'ENTRY_CREATE' and 'ENTRY_MODIFY'.

据我所知,一个新文件(从其他未被监视的目录复制而来)必须只创建一个事件,即:'ENTRY_CREATE'。

谁能解释为什么会创建额外事件“ENTRY_MODIFY”?

我的代码:

public void watch() {
    WatchKey key = watcher.poll();

    //log.info("Watcher scheduler running. Watch key {}", key.hashCode());

    if (key != null) {
        Workflow workflow = keys.get(key);
        log.info("Runing watcher for key '{}'  and workflow {}", key.hashCode(), workflow.getName());
        File hotFolder = new File(workflow.getFolderPath());
        Path dir = hotFolder.toPath();

        for (WatchEvent<?> event : key.pollEvents()) {
            WatchEvent<Path> ev = cast(event);
            Path name = ev.context();
            Path child = dir.resolve(name);

            log.info("Polling event for name {} and child {} and dir {}", name.toFile(), child.toFile(), dir.toFile());

            if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS))
                continue;

            try {
                switch (event.kind().name()) {
                case "ENTRY_CREATE":
                    log.info("New file {}", child.toFile());
                    fileService.processNewFile(child.toFile(), workflow);
                    break;
                case "ENTRY_MODIFY":
                    log.info("File modified.... {}", child.toFile());
                    fileService.processModifiedFile(child.toFile(),
                            workflow);
                    break;
                default:
                    log.error("Unknown event {} for file {}", event.kind()
                            .name(), child.toFile());
                    break;
                }
                // Operation op = Operation.from(event.kind());
                // if (op != null)
                // publisher.publishEvent(new FileEvent(child.toFile(),
                // workflow, op));
            } catch (Throwable t) {
                log.warn("Error while procesing file event", t);
            }
        }

        key.reset();
    }
}

所以当我复制文件时,说 name = "abc.txt",日志显示:
新文件 abc.txt
文件已修改.... abc.txt


强烈征求任何意见。

最佳答案

检查 WatchService JavaDoc 中的“平台依赖项”部分.

观察者在您描述的情况下表现正常。严格来说,当您将文件复制到文件夹时,文件实际上是先创建然后修改。

使用 WatcherService 时需要考虑很多事情,它的行为变化很大,例如:

  • 操作系统
  • 加密光盘
  • 网络共享
  • ...

关于当新文件添加到监视文件夹时,Java NIO 监视服务创建了 'ENTRY_CREATE' 和 'ENTRY_MODIFY',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33753561/

相关文章:

java - Ice Cream Sandwich 无法识别 HTML 中的换行符

JAVA:如何确保 1 方法在调用下一个方法之前已完成?

java - SKIP_SIBLINGS 和 SKIP_SUBTREE 之间的区别

Scala 文件哈希

java - 使用 Java WatchService 监视文件夹中的文件夹

java - 观察者模式: delay action after event trigger

java - 我无法在 ASM JAVA 中加载 invokedynamic 的局部变量

Java NIO 为什么 Selector 必须以非阻塞模式与 Channel 一起工作?

java - WatchService 在 CentOS 上使用 100% 的 CPU

java - 使用 Solrj 进行基本身份验证时,出现错误 "Caused by: java.net.SocketException: Connection reset"