10

我想使用 Java NIO 观看(监视)多个目录 WatchService。我的问题是要观看的目录数量是动态的,用户可以将任意数量的目录添加到WatchService. 这是可以实现的吗?

4

4 回答 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 回答