我實現了一個文件觀察器,但我注意到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. Java nio WatchService:觀看Windows驅動器列表
- 2. FluentNHibernate自動映射不生成映射
- 3. 根據組成員映射驅動器
- 4. 使用WatchService監視映射網絡驅動器上的多個目錄
- 5. 映射網絡驅動器
- 6. 映射Sharepoint驅動器
- 7. Delphi - 映射驅動器ipaddress
- 8. 映射網絡驅動器
- 9. 映射網絡驅動器
- 10. 在R - 映射驅動器setwd?
- 11. Python Win32 - DriveInfo在映射驅動器
- 12. 自動生成Hibernate映射文件
- 13. 從本地驅動器識別映射驅動器
- 14. Fluent配置不生成映射文件
- 15. ProGuard不會生成映射文件
- 16. 詹金斯無法看到映射驅動器
- 17. 將HDFS文件映射到外部驅動器時出錯
- 18. PowerShell新PSD驅動器沒有映射驅動器
- 19. 當源中不存在屬性時自動映射器映射
- 20. 複製文件到映射的驅動器不工作
- 21. 映射網絡驅動器上的FileSystemWatcher
- 22. Gradle - 如何映射驅動器?
- 23. 如何使用PowerShell映射驅動器
- 24. 映射網絡驅動器與陣列
- 25. tomcat 7訪問映射驅動器
- 26. 如何ping映射的驅動器
- 27. 將UNC源映射爲驅動器
- 28. 將ftp映射到C#驅動器#
- 29. 將驅動器映射到SharePoint 2010
- 30. VMWare VMDK映射到Windows驅動器號
是的,但我正在看的目錄是在我運行我的監視器的同一臺機器上。因此,無論是通過網絡還是本地機器進行傳輸,操作系統都應該意識到這一點,否則如何完成傳輸。這是有道理的,Windows正在輪詢映射的驅動器,但我不明白Unix如何不知道通過本地文件夾上的網絡所做的更改。 – Ramcis
@Ramcis:在Linux上,通過NFS安裝網絡共享,NFS設計爲無狀態協議。因此,服務器根本不知道有多少客戶端正在訪問哪個文件。該設計有一些優點(如較少的開銷)和一些缺點... – Robert