我想使用 Java NIO 观看(监视)多个目录 WatchService
。我的问题是要观看的目录数量是动态的,用户可以将任意数量的目录添加到WatchService
. 这是可以实现的吗?
问问题
8541 次
4 回答
12
可以使用相同的WatchService
. 每条路径都有自己的WatchKey
. take()
or将poll()
返回WatchKey
对应于被修改的路径。
有关详细信息,请参阅Java 的 WatchDir 示例。
于 2013-10-10T17:07:34.440 回答
3
遵循与先前答案相同的链接: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();
}
于 2020-02-06T18:46:43.347 回答
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 示例
于 2017-02-01T08:33:15.950 回答
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();
}
}
}
于 2021-03-11T20:03:59.090 回答