当前位置: 首页 > 知识库问答 >
问题:

JavaNIO Watch Service在将新文件添加到Watch文件夹时创建了ENTRY_CREATE和ENTRY_MODIFY

蔚学林
2023-03-14

我看到一个奇怪的行为(我不确定这是预期的行为)使用java。尼奥。文件值班服务。

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

ENTRY_CREATE和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


任何意见都被高度征求。

共有2个答案

劳嘉实
2023-03-14

我想,这个问题已经在这里得到了回答。

例如,Java:WatchService在复制内容之前得到通知

换句话说,事件是由您的操作系统生成的。您有两个事件,这意味着您的操作系统以非原子方式执行复制。如果您试图读取介于ENTRY_CREATE和ENTRY_MODIFY之间的文件,它将不一致。但同样,这取决于你的操作系统。例如,在Windows 7上,对于大文件,我会得到一次ENTRY_CREATE,两次ENTRY_MODIFY。因此,您实际上无法确定文件是否成功复制,您必须提出依赖于应用程序/操作系统的指标。

公羊凌
2023-03-14

查看WatchService JavaDoc中的“平台依赖项”部分。

观察者在你描述的情况下行为正确。严格地说,当你把一个文件复制到一个文件夹中时,文件实际上是被创建并修改的。

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

  • 操作系统
 类似资料:
  • 问题 你需要在程序执行时创建一个临时文件或目录,并希望使用完之后可以自动销毁掉。 解决方案 tempfile 模块中有很多的函数可以完成这任务。 为了创建一个匿名的临时文件,可以使用 tempfile.TemporaryFile : from tempfile import TemporaryFile with TemporaryFile('w+t') as f: # Read/writ

  • 问题内容: 我正在Swift中构建一个简单的程序,它应该将具有特定扩展名的文件复制到另一个文件夹中。如果该文件夹存在,程序将只将它们复制到该文件夹​​中;如果该文件夹不存在,则程序必须先将其复制。 运行此代码将正确识别MTS文件,但会导致“添加失败…”,我在做什么错? 问题答案: 从文档中: 放置的副本的路径。此路径必须在新位置包含文件或目录的名称。… 您必须将文件名附加到调用的目标目录中 (为S

  • 我目前正在为《我的世界》创建一个mod。这是另一个电脑模式,我需要它来存储所有的文件和文件夹,用户在计算机上创建到计算机自己的个人文件夹。对于一台计算机的每个实例,将创建一个具有该计算机编号的文件夹,该文件夹将在该特定计算机内的所有文件和文件夹中分配。例如:假设这些文件夹将位于目录c://mc/mods,那么第一台计算机将具有文件夹c://mc/mods/1,第二台c://mc/mods/2,依此

  • 问题内容: 我想创建一个zip文件。在zip文件中添加一个文件夹,然后在该文件夹中添加一堆文件。 因此,我想得到一个压缩文件,里面只有一个文件夹。 我不知道在zip文件或其他内容中包含文件夹是否是一种不好的做法,但是google在这个问题上没有给我任何帮助。 我从这个开始: 摘自:http : //mail.python.org/pipermail/python- list/2006-August

  • 我正在使用笔记本中的pyspark,我不处理SparkSession的创建。我需要加载一个jar,其中包含一些在处理rdd时要使用的函数。这是一件你可以很容易地用罐子做的事,但我在我的特殊情况下做不到。有没有办法访问spark scala上下文并调用addJar方法?我尝试使用JavaGateway(sparksession.\u jvm…)但到目前为止还没有成功。有什么想法吗? 谢谢纪尧姆