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

Java:WatchService在复制内容之前得到通知,java,windows,watchservice,Java,Windows,Watchservice,我试着将一个非常小的文件复制粘贴到一个由手表服务观察到的文件夹中。第一次很好,但是在所有后续的复制和粘贴操作中,我得到一个例外,即另一个进程已经处理了该文件。通过实验,我发现我的服务在Windows创建文件时得到通知,而不是在复制文件内容时得到通知。如果锁定该文件,Windows将无法复制任何数据,并且该文件为空。另一方面,如果我将文件移动到目录中,一切正常 这是来自Windows的错误吗?我无法在mac或Linux工作站上测试它。也许只是因为我没有能力。感谢您的帮助 我的代码如下所示: try

我试着将一个非常小的文件复制粘贴到一个由手表服务观察到的文件夹中。第一次很好,但是在所有后续的复制和粘贴操作中,我得到一个例外,即另一个进程已经处理了该文件。通过实验,我发现我的服务在Windows创建文件时得到通知,而不是在复制文件内容时得到通知。如果锁定该文件,Windows将无法复制任何数据,并且该文件为空。另一方面,如果我将文件移动到目录中,一切正常

这是来自Windows的错误吗?我无法在mac或Linux工作站上测试它。也许只是因为我没有能力。感谢您的帮助

我的代码如下所示:

try (WatchService watchService = importPath.getFileSystem().newWatchService()) {
  importPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
  handleExistingFiles();

  try {
    do {
      WatchKey watchKey = watchService.take();
      if (!watchKey.isValid()) {
        continue;
      }

      boolean hasCreationEvents = false;
      for (WatchEvent<?> event : watchKey.pollEvents()) {
        hasCreationEvents |= event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE);
      }
      watchKey.reset();

      if (hasCreationEvents) {
        handleNewFiles();
      }
    }
    while (!Thread.currentThread().isInterrupted());
  }
  catch (InterruptedException ignoredEx) {
    Thread.currentThread().interrupt();
  }
}
try(WatchService WatchService=importPath.getFileSystem().newWatchService()){
导入路径注册(watchService、StandardWatchEventTypes.ENTRY\u CREATE);
handleExistingFiles();
试一试{
做{
WatchKey WatchKey=watchService.take();
如果(!watchKey.isValid()){
继续;
}
布尔hasCreationEvents=false;
for(WatchEvent事件:watchKey.pollEvents()){
hasCreationEvents |=event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE);
}
watchKey.reset();
如果(hasCreationEvents){
handleNewFiles();
}
}
而(!Thread.currentThread().isInterrupted());
}
捕获(中断异常信号索引){
Thread.currentThread().interrupt();
}
}

复制操作并不总是原子的

使用atomic copy(或move)时,您将获得一个创建事件的单个条目,该事件引用的文件将完整并可供读取

如果复制不是原子的,则在创建文件时将收到一个ENTRY\u CREATE事件,然后在复制操作写入文件时将收到一个或多个ENTRY\u MODIFY事件

没有简单的方法可以确定复制操作何时完成对文件的写入并将其释放。根据操作系统和文件系统的不同,在试图打开文件进行读取时,如果文件被复制操作锁定,则可能会出现FileNotFoundException;或者,您可以成功打开文件,但在实际读取文件时,会得到部分内容


您必须实施一些启发式方法,如在输入后立即尝试读取文件\u创建并在初始读取失败时重新安排读取时间。

以及您观看的文件是由什么程序创建的?不要忘记,程序通常会写入一个临时文件,然后才覆盖原始文件。这是我们的一个旧程序,它创建一个输出文件,将数据传输到当前文件。我将检查文件是如何写入的,但正如下面提到的Oleg,可能会出现两个事件,一个是创建事件,一个是修改事件,我响应了错误的事件…感谢您的提示。我将代码从ENTRY\u CREATE更改为ENTRY\u MODIFY,并没有发现任何问题,至少在windows上是这样。我会和其他操作系统一起检查它,希望它也能在那个里工作。在我处理完文件后,它将被删除。我想这样就可以了:)我能够在MAC系统上测试它。它也在那里工作。谢谢!耶