我想使用Java NIO WatchService
观看(监控)多个目录。
我的问题是要监视的目录数是动态的,用户可以向WatchService
添加任意数量的目录。这可以实现吗?
答案 0 :(得分:8)
可以使用相同的WatchService
注册多个路径。每条路径都有自己的WatchKey
。然后,take()
或poll()
将返回与修改后的路径对应的WatchKey
。
有关详细信息,请参阅Java's WatchDir example。
答案 1 :(得分:2)
我只想解释如何使用WatchService
完成此操作。
以下是一段代码,说明了如何使用一个WatchService
实例并听取两个Paths
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<>();
Path plugins = Paths.get(INSTANCE.getPluginPath());
logger.info(String.format("Scanning %s ...", plugins));
registerAll(plugins);
Path drivers = Paths.get(INSTANCE.getDriverPath());
logger.info(String.format("Scanning %s ...", drivers));
registerAll(drivers);
该示例基于Oracle Example
答案 2 :(得分:2)
遵循与先前答案相同的链接:Oracle WatchDir。
您可以先创建WatchService
:
WatchService watchService = FileSystems.getDefault().newWatchService();
目前,您可以将多个路径添加到同一WatchService
:
Path path1 = Paths.get("full\path\1\\");
path1.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE);
Path path2 = Paths.get("full\path\2\\");
path2.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE);
然后您可以按以下方式管理事件:
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println(
"Event kind:" + event.kind()
+ ". File affected: " + event.context() + ".");
}
key.reset();
}
现在,如果您想获得有关在何处引发事件的更多信息,则可以创建一个映射以通过示例链接键和路径(您可以根据需要考虑将变量创建为类级别):>
Map<WatchKey, Path> keys;
在此示例中,您可以将路径包含在列表中,然后需要循环到其中,并将每个路径添加到相同的WatchService
:
for (Path path : paths) {
WatchKey key = path.register(
watchService,
StandardWatchEventKinds.ENTRY_CREATE);
keys.put(key, path);
}
现在可以管理事件了,您可以添加类似的内容:
WatchKey key;
while ((key = watchService.take()) != null) {
Path path = keys.get(key);
// More code here.
key.reset();
}
答案 3 :(得分:0)
为几个固定目录添加一个完整的简单解决方案。这个例子有 3 个将被监控的目录,当我正在寻找一个文件时,我会处理它。在 Linux 中使用这种方法而不是我需要 root 访问权限的端口侦听器。
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.HashMap;
import java.util.Map;
public class WatchDirSimple {
public static void main(String[] args) {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
Map<WatchKey,Path> keys = new HashMap<WatchKey,Path>();
WatchDirSimple watchDirSimple = new WatchDirSimple();
WatchKey key;
Path dir;
dir = Paths.get(System.getProperty("user.home")+File.separator + "Documents\\PROD_Data\\ODBI");
key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
keys.put(key, dir);
dir = Paths.get(System.getProperty("user.home")+File.separator + "Documents\\PROD_Data\\ODBI\\@fred");
key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
keys.put(key, dir);
dir = Paths.get(System.getProperty("user.home")+File.separator + "Documents\\PROD_Data\\ODBI\\CMODupgrade");
key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
keys.put(key, dir);
for (;;) {
try {
key = watcher.take();
} catch (InterruptedException x) {
return;
}
dir = keys.get(key);
if (dir == null) {
System.err.println("WatchKey not recognized!!");
continue;
}
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind kind = event.kind();
// Context for directory entry event is the file name of entry
WatchEvent<Path> ev = (WatchEvent<Path>)event;
Path name = ev.context();
Path child = dir.resolve(name);
// print out event
System.out.format("%s: %s\n", event.kind().name(), child);
}
// reset key and remove from set if directory no longer accessible
boolean valid = key.reset();
if (!valid) {
keys.remove(key);
// all directories are inaccessible
if (keys.isEmpty()) {
break;
}
}
}
watchDirSimple.register(dir, watcher, keys);
} catch (IOException e) {
e.printStackTrace();
}
}
}