2013-01-12 29 views
10

我正在使用WatchService來同步數據文件與應用程序工作臺。當我重命名/移動觀看的目錄時,我沒有收到任何事件,WatchKey也不會失效。我仍然從重命名的目錄中獲取事件,但據我所知,除了WatchKey.watchable()之外,沒有辦法找到WatchKey的實際路徑,但仍然返回原始目錄路徑。我想避免需要鎖定監視的目錄以應對更改,因爲我想盡可能保持應用程序的輕量級。Java7 WatchService - 如何檢測實際觀看目錄的重命名/移動

我曾經歷過這個問題,JDK 7u10在Windows 7

你知道這個問題什麼解決辦法沒有鎖定的目錄或者看所有目錄的根?

UPDATE

在Linux上我觀察到相同的行爲。

到目前爲止,我似乎有三種選擇。

1)依靠用戶的紀律,他/她不會移動數據目錄。我不太喜歡這個選項,因爲它可能會導致未定義的行爲。

2)使用更廣泛的非標機庫

3)創建優越的目錄監管機構的層次。這些事件只接受ENTRY_DELETE事件,因爲此事件(或OVERFLOW)必須在實際觀看的目錄被移動或刪除並因此無效時出現。

+0

的Javadoc指定,這裏使用的是本地可用的機制,你有沒有試過和搜索Win7的機制是如何起作用在這種情況下? – fge

+0

Windows上的本地機制使用目錄句柄,當目錄被重命名/移動但發送了特定事件時,該目錄句柄未更改。這不會是一個問題,但在java中,我沒有看到任何方式來檢測這些窗口特定事件,也沒有任何方式來獲取和檢查實際的目錄句柄值。 – rjezek

回答

6

我的理解是,重命名一個目錄將生成新老父目錄上的文件系統事件,而不是重命名的目錄。根據對Can iNotify tell me where a monitored file is moved?的回答,操作系統無法告訴你在什麼地方被移到了什麼地方,除非你正在監視目的地目錄。 (除此之外,在Java 7/8 MOVE事件不被手錶服務實現處理。)

UPDATE

你可以嘗試jpathwatch項目,增加了(platform specific)使用擴展事件的支持標準的Java7 WatchService API。

參考文獻:

+0

那麼,我真的不需要知道我的目錄是在哪裏移動的。這將是很好的知道它被移動,所以我可以根據新的情況改變WatchKey註冊。我已經檢查過JRE實現,看起來他們只是拋棄了系統中的這些事件。到目前爲止,似乎在當前實現中處理這個問題的唯一方法是觀察所有根目錄。它看起來不太漂亮,但我想我可以這樣解決它,或者你有什麼更好的主意? – rjezek

+0

根據jpathwatch庫中的[KEY_INVALID](http://jpathwatch.sourceforge.net/name/pachler/nio/file/ext/ExtendedWatchEventKind.html#KEY_INVALID),似乎這是一個孤立的Windows問題,因爲其他系統使WatchKey無效當它移動時。的確,問題在於標準的Java 7 WatchService是否也是這樣的,因此我將在Linux上進一步研究它的行爲並將結果放在這裏。 – rjezek

相關問題