Java7 WatchService - 尝试删除递归监视的嵌套目录时出现访问被拒绝错误(仅限 Windows)
我按照 Watching a Directory for Changes Java7 nio2 教程递归地进行操作使用代码示例监视目录的全部内容 WatchDir.java。
虽然这在 Linux 和 Mac 上运行良好,但在 Windows 上(在 Vista 和 7 上测试),尝试使用 Windows 资源管理器删除嵌套、监视的文件夹会失败,并显示类似于“拒绝访问:您需要执行此操作的权限”的消息。存在于嵌套目录之一中。
例如,如果我在 Windows 中查看嵌套文件夹树:
-- Folder A
-- Folder A1
-- File F
并尝试删除文件夹 A,我会收到上述“访问被拒绝”错误。但是,如果我执行以下操作,则效果很好:
- 删除文件夹 A1,然后删除文件夹 A
- 删除文件 F,然后删除文件夹 A
有没有办法使用 nio2 WatchService 递归地监视嵌套目录,但不会像程序正在访问嵌套文件一样?
I followed the Watching a Directory for Changes Java7 nio2 tutorial to recursively monitor the entire contents of a directory using the code sample WatchDir.java.
While this works well on Linux and Mac, on Windows (tested on Vista and 7), trying to delete nested, watched folders using Windows Explorer fails with a message akin to "Access Denied: You need permission to perform this action" when a file exists in one of the nested directories.
For example, if I watch a nested folder tree in Windows:
-- Folder A
-- Folder A1
-- File F
and try to delete Folder A, I get the said Access Denied error. However, it works fine if I:
- Delete Folder A1 then delete Folder A
- Delete File F then delete Folder A
Is there a way to use the nio2 WatchService to recursively watch a nested directory, but not act as though a program is accessing nested files?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您正在 Windows 上监视某个目录,则 WatchService 实现具有该目录的开放句柄(这就是 Windows 的工作方式)。该打开句柄不会阻止目录被删除,但它确实会阻止目录的父目录被立即删除。一旦您删除了监视的目录,句柄就会关闭,但您可能会在句柄关闭之前尝试删除该目录。当发生这种情况时,您将看到您所看到的访问被拒绝的情况。我认为如果您重试,它对您来说效果很好,这是因为在您重试时句柄将关闭。
如果您在
register
调用中指定ExtendedWatchEventModifier.FILE_TREE
修饰符,Windows 上的 Sun JRE 可以使用 Windows 的监视子树功能,这有助于绕过此问题,因为它只创建一个文件句柄。If you are watching a directory on Windows then the WatchService implementation has an open handle to that directory (that's the way that Windows works). That open handle doesn't prevent the directory from being deleted but it does prevent the directory's parent from being deleted immediately. As soon as you delete the watched directory then the handle is closed but it's possible that you will attempt to delete the directory before the handle is closed. When that happens you will get the access denied that you are seeing. I assume it works fine for you if you retry and this is because the handle will be closed by the time you retry.
The Sun JRE on Windows can use Windows' watch subtree capability if you specify the
ExtendedWatchEventModifier.FILE_TREE
modifier in theregister
call, which can help bypass this issue as it creates only one file handle.