我實現了一個文件觀察器,但我注意到java nio文件觀察器不會爲在映射驅動器上覆制的文件生成事件。例如,我在Unix上運行文件觀察器來觀察映射到窗口(H:\
)上的本地目錄(/sharedfolder
),然後我在該目錄中放置了一個文件(H:\
),但文件觀察器沒有生成任何事件。現在,如果我在Windows上運行文件觀察器來觀察映射的驅動器(H:\
),它指向unix路徑(/sharedfolder
),並且從unix中將文件放入此文件夾,則文件觀察器將識別該更改並生成一個事件。它看起來像一個錯誤,或者可能是我錯過了一些事情,有什麼想法?Java WatchService在觀看映射驅動器時不生成事件
回答
JDK中的文件監視功能與平臺相關,因爲它使用本機庫,因此它可能在不同的平臺上表現不同。我很驚訝它適用於網絡驅動器--Windows必須輪詢網絡映射的驅動器以進行更改,而Linux不會(正常情況下我應該這麼說)。
通常這種在OS內核中實現的監視,顯然知道哪些文件在本地被修改/創建/等,但是OS沒有簡單的方法知道網絡驅動器上發生了什麼,因爲它沒有排他控制超過它。
我在觀看遠程Windows目錄上的日誌文件內容的Python腳本時遇到了類似的問題。
這是我的答案。
當映射來自Unix的遠程驅動器,在使用/etc/fstab
//xxx.xxx.xxx.xxx/shareddrive /media/shareddrive cifs username=xxxx,password=xxxx,**directio** 0 0
您可以使用證書文件,以避免在明文密碼。
該命令可能會根據unix版本而改變,這是在debian下測試的。 它應該按預期工作。 你能告訴我它是否有效嗎? 我計劃在Java中實現相同的東西,所以我的答案也可能對我有用。
這不再工作順便說一句。我認爲它的工作方式有點片面(反正在ubuntu上),但在最近的更新之後,它完全停止了工作。我添加了一個答案來描述我可怕的解決方法。 – rubyruy
我有同樣的問題試圖通過CIFS觀看掛載的Windows共享。 看來不可能得到filesystem events for CIFS mounts。
Java 7 NIO FileWatcher的Linux實現使用inotify。 Inotify是一個用於注意文件系統更改的Linux內核子系統,適用於本地目錄,但顯然不適用於CIFS mounts。
在Oracle上,修復this bug似乎並不是高優先級。 (這是他們的責任?更多的操作系統問題...)
JNotify也使用inotify在Linux系統上,所以這也是沒有選擇。
所以映射驅動器監測不幸似乎僅限於輪詢:
- Apache VFS DefaultFileMonitor輪詢目錄(安裝股)基於標準的Java API
- 文件輪詢。
- 自定義文件輪詢與jCIFS(這樣的比例並不需要安裝在主機上)
我可能會嘗試在Apache VFS顯示器,因爲它檢測到文件的創建,更新和刪除出盒子。它需要安裝共享,但是這給OS賦予了CIFS連接的責任,而不是我的應用程序。
我也碰到過這個,並得出了與其他人一樣的結論(CIFS + inotify = no go)。然而,由於我的工作流恰巧依賴於依賴inotify的遠程掛載和自動編譯工具,我最終構建了一個(相當絕望的& hacky)解決方案,它基本上只是使用輪詢來監視變化,然後觸及同樣的文件再次在安裝的一面,其中似乎引發inotify事件。這不是我最自豪的時刻。
話雖如此,它的工作,所以,可享受:http://github.com/rubyruy/watchntouch
我有同樣的問題。我已經通過在de main類中創建一個新線程並定期觸摸這些文件來解決這個問題,從而引發了一個新的更改事件。
該示例每10秒輪詢一次目錄會觸摸一下。
package com.ardevco.files;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.List;
public class Touch implements Runnable {
private Path touchPath;
public Touch(Path touchPath) {
this.touchPath = touchPath;
this.checkPath = checkPath;
}
public static void touch(Path file) throws IOException {
long timestamp = System.currentTimeMillis();
touch(file, timestamp);
}
public static void touch(Path file, long timestamp) throws IOException {
if (Files.exists(file)) {
FileTime ft = FileTime.fromMillis(timestamp);
Files.setLastModifiedTime(file, ft);
}
}
List<Path> listFiles(Path path) throws IOException {
final List<Path> files = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
files.addAll(listFiles(entry));
}
files.add(entry);
}
}
return files;
}
@Override
public void run() {
while (true) {
try {
for (Path path : listFiles(touchPath)) {
touch(path);
}
} catch (IOException e) {
System.out.println("Exception: " + e);
}
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
System.out.println("Exception: " + e);
}
}
}
}
- 1. FluentNHibernate自動映射不生成映射
- 2. 根據組成員映射驅動器
- 3. 使用WatchService監視映射網絡驅動器上的多個目錄
- 4. 映射網絡驅動器
- 5. 映射網絡驅動器
- 6. 映射Sharepoint驅動器
- 7. Delphi - 映射驅動器ipaddress
- 8. Python Win32 - DriveInfo在映射驅動器
- 9. ProGuard不會生成映射文件
- 10. Fluent配置不生成映射文件
- 11. PowerShell新PSD驅動器沒有映射驅動器
- 12. 當源中不存在屬性時自動映射器映射
- 13. Gradle - 如何映射驅動器?
- 14. 如何使用C#映射驅動器?
- 15. 如何使用PowerShell映射驅動器
- 16. Gem install尋找映射驅動器
- 17. Caspol,虛擬機,映射驅動器,VS2010
- 18. 將驅動器映射到SharePoint 2010
- 19. Cygwin訪問Windows UNC映射驅動器
- 20. Cassandra C#驅動程序映射器
- 21. SMB和Python與映射驅動器
- 22. VMWare VMDK映射到Windows驅動器號
- 23. 僅在連接到域時映射網絡驅動器
- 24. Railsinstaller試圖安裝完成後使用映射的驅動器
- 25. 在RunOnce批處理文件中映射驅動器
- 26. 使用Java的映射網絡驅動器未連接
- 27. 從休眠映射文件生成DDL
- 28. Java事件生成
- 29. 如何處理JAVA WatchService溢出事件?
- 30. Java + Flash =>事件驅動?
是的,但我正在看的目錄是在我運行我的監視器的同一臺機器上。因此,無論是通過網絡還是本地機器進行傳輸,操作系統都應該意識到這一點,否則如何完成傳輸。這是有道理的,Windows正在輪詢映射的驅動器,但我不明白Unix如何不知道通過本地文件夾上的網絡所做的更改。 – Ramcis
@Ramcis:在Linux上,通過NFS安裝網絡共享,NFS設計爲無狀態協議。因此,服務器根本不知道有多少客戶端正在訪問哪個文件。該設計有一些優點(如較少的開銷)和一些缺點... – Robert