Java7 WatchService - 访问被拒绝错误,尝试递归删除嵌套目录(仅限Windows)

17

我按照Java7 nio2教程中的“监视目录变化”指南,使用代码示例WatchDir.java递归监视整个目录的内容。

虽然这在Linux和Mac上运行良好,但在Windows上(测试过Vista和7),尝试使用Windows Explorer删除嵌套的、被监视的文件夹时,如果嵌套目录中存在文件,则会失败,并出现类似于“访问被拒绝:您需要权限才能执行此操作”的消息。

例如,如果我在Windows中监视一个嵌套的文件夹树:

-- Folder A
   -- Folder A1
      -- File F

当我尝试删除文件夹A时,出现了拒绝访问的错误。但是,如果我这样做:

  • 先删除文件夹A1,然后再删除文件夹A
  • 删除文件F,然后再删除文件夹A

有没有一种方法可以使用nio2 WatchService递归地监视嵌套目录,但不会像程序访问嵌套文件那样操作它们?

1个回答

19
如果你在 Windows 上观察一个目录,那么 WatchService 实现会对该目录保持一个打开的句柄(这就是 Windows 的工作方式)。这个打开的句柄并不会阻止目录被删除,但它确实会防止目录的父级目录立即被删除。当你删除被观察的目录时,句柄会被关闭,但可能会出现在句柄关闭之前尝试删除目录的情况。当这种情况发生时,你会遇到访问被拒绝的错误。我假设如果重试操作,它应该可以正常运行,因为在下一次重试之前,句柄将已经被关闭。
在 Windows 平台上,Sun JRE 可以使用 Windows 监视子树功能,只需在 `register` 调用中指定 `ExtendedWatchEventModifier.FILE_TREE` 修改器即可。这可以帮助避免此问题,因为它只创建一个文件句柄。

感谢提供有关特定于Windows的FILE_TREE修饰符的注释。在Java 7 Bug数据库中的相关错误中有一个类似的评论(我错过了):http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=76a42b61021a94ffffffffa049f7587fd4149?bug_id=6972833 - FR.
1
还要注意,在Eclipse中,我不得不将由于rt.jar上的访问限制引起的错误降低为警告。请参见http://lkamal.blogspot.com/2008/09/eclipse-access-restriction-on-library.html。 - FR.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接