Java监视服务似乎重新创build删除的文件。 到底是怎么回事?

当由WatchService监视的目录被删除时,其父目录不会立即反映其文件的listFiles方法中的删除,并且不能被删除。 在整个服务被明确停止之前,父母的后果似乎是:

  1. 推荐的用于删除非空目录失败的recursion解决scheme 。
  2. 在正常终止时不执行deleteOnExit
  3. 调用删除返回false并对文件系统没有影响。

为了演示,这个testing代码:

import java.io.*; import java.nio.file.*; class DirectoryTester { static WatchService watcher; static { try{watcher = FileSystems.getDefault().newWatchService();} catch (IOException e) {e.printStackTrace();} } public static void main(String[] args) throws IOException { String SEPARATE = System.getProperty("file.separator"); String testDirName = System.getProperty("user.dir") + SEPARATE + "testDir"; String subDirName = testDirName + SEPARATE + "subDir"; String fileName = subDirName + SEPARATE +"aFile"; create(fileName); Paths.get(subDirName).register(watcher, StandardWatchEventKinds.ENTRY_DELETE); delete(new File(testDirName)); } static void create(String nameOfFile) throws IOException { new File(nameOfFile).getParentFile().mkdirs(); Files.createFile(Paths.get(nameOfFile)); System.out.println("Created " + nameOfFile); } static void delete(File toDelete) throws IOException { if (toDelete.isDirectory()) for (File c : toDelete.listFiles()) delete(c); int numContainedFiles = toDelete.listFiles() != null ? toDelete.listFiles().length : 0; if (!toDelete.delete()) { System.out.println("Failed to delete " + toDelete + " containing " + numContainedFiles); } else { System.out.println("Deleted " + toDelete + " containing " + numContainedFiles); } } } 

在windows上给出以下输出,这与testDir在文件系统上没有被删除相对应。

 Created C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir\aFile Deleted C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir\aFile containing 0 Deleted C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir containing 0 Failed to delete C:\Dropbox\CodeSpace\JavaTestbed\src\testDir containing 1 

如果我在subDir删除后放置一个断点,我可以看到它已经在文件系统上被删除了。 从断点恢复会导致最后的删除操作结束,这表明这可能是Watch服务线程所做更改的可见性的问题。 有人知道这里发生了什么,如果这是一个错误? 我实际上想要做的是删除监视的目录,而不停止对其他目录的监视,因为似乎没有API提供的未注册path方法。其他标准的Java方法是什么?

可能相关:

http://bugs.sun.com/view_bug.do?bug_id=6972833

WatchService对每个观看的目录都有一个打开的句柄。 如果一个监视目录被删除,那么WatchService会关闭这个句柄,这样目录条目可以从父目录中删除。 问题出现在实用程序和应用程序,希望能够立即删除父目录,因为它可能需要几个毫秒的监视服务来获取通知和关闭句柄。 如果在那个时候该工具试图删除父目录,那么它将失败。 目前我们还没有解决这个问题的方法。