我想使用Java NIO的WatchService
监视多个目录。
我的问题是要监视的目录数量是动态的,用户可以向WatchService
添加任意数量的目录。这是否可行?
我想使用Java NIO的WatchService
监视多个目录。
我的问题是要监视的目录数量是动态的,用户可以向WatchService
添加任意数量的目录。这是否可行?
可以使用相同的WatchService
来注册多个路径。每个路径都有自己的WatchKey
。然后,take()
或poll()
将返回对应于被修改的路径的WatchKey
。
请参见Java的WatchDir示例以获取详细信息。
按照之前的答案,可以使用以下链接: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();
}
我只是试图解释如何使用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);
为几个固定目录添加一个完整的简单解决方案。此示例有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();
}
}
}