【问题标题】:Java7 WatchService - How to detect rename/move of the actual watched directoryJava7 WatchService - 如何检测实际监视目录的重命名/移动
【发布时间】:2013-01-12 13:28:45
【问题描述】:

我正在使用WatchService 与应用程序工作台同步数据文件。当我重命名/移动监视目录时,我没有收到任何事件,WatchKey 也不会变得无效。我仍然从重命名的目录中获取事件,但据我所知,除了WatchKey.watchable() 之外,没有办法找到 WatchKey 的实际路径,但它仍然返回原始目录路径。我想避免需要锁定监视目录以防止更改,因为我希望使应用程序尽可能轻量级。

我在 Windows 7 上使用 JDK 7u10 时遇到过这个问题

您知道在不锁定目录或查看所有目录到根目录的情况下解决此问题的任何解决方法吗?

更新

在 Linux 上我观察到了同样的行为。

到目前为止,我似乎有三个选择。

1) 依靠用户的纪律,他/她不会移动数据目录。我不太喜欢这个选项,因为它可能会导致未定义的行为。

2) 使用更广泛的非标准原生库

3) 在上级目录上创建看门狗的层次结构。这些将仅接受 ENTRY_DELETE 事件,因为此事件(或 OVERFLOW)必须在实际监视的目录被移动或删除时出现,因此无效。

【问题讨论】:

  • Javadoc 指定这使用了本机可用的机制,您是否尝试并搜索过 Win7 的机制在这种情况下的作用?
  • Windows 上的本机机制使用目录句柄,在重命名/移动目录但发送特定事件时不会更改目录句柄。这不是问题,但在 java 中,我看不到任何检测这些 Windows 特定事件的方法,也看不到任何获取和检查实际目录句柄值的方法。

标签: java io java-7 watchservice


【解决方案1】:

我的理解是重命名目录会在新旧父目录上生成文件系统事件,而不是在重命名的目录上。根据Can iNotify tell me where a monitored file is moved? 的回答,除非您正在监视目标目录,否则操作系统无法告诉您某些东西被移动到了哪里。 (此外,在 Java 7/8 中 MOVE 事件不由 watch 服务实现处理。)

更新

您可以尝试使用标准 Java7 WatchService API 添加对 (platform specific) 扩展事件的支持的 jpathwatch 项目。

参考资料:

【讨论】:

  • 好吧,我真的不需要知道我的目录被移动到了哪里。知道它被移动就好了,所以我可以根据新情况更改 WatchKey 注册。我检查了 JRE 的实现,似乎他们只是从系统中丢弃了这些事件。到目前为止,似乎用当前实现处理这个问题的唯一方法是观察所有目录直到根目录。它看起来不是很漂亮,但我想我可以这样解决它或者你有什么更好的主意?
  • 根据 jpathwatch 库中的KEY_INVALID,这似乎是一个孤立的 Windows 问题,因为其他系统在移动 WatchKey 时会使其无效。事实上,问题是标准的 Java 7 WatchService 是否也有这样的行为,所以我将进一步研究它在 Linux 上的行为并将我的结果放在这里。
猜你喜欢
  • 1970-01-01
  • 2011-09-09
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 2022-12-05
  • 2021-05-29
  • 2012-02-29
  • 1970-01-01
相关资源
最近更新 更多