确定从监视事件中删除的文件的类型



我有一个WatchService监视ENTRY_CREATEENTRY_DELETEENTRY-MODIFY事件的目录树。问题是WatchEvent<?>的上下文只提供一个 Path 对象。在删除事件中,我不确定路径是否引用了常规文件的目录。

WatchKey key = null;
try {
    key = watcher.take();
} catch (InterruptedException e) {
    e.printStackTrace();
}
for (WatchEvent<?> event : key.pollEvents()) {
    if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
        continue;
    }
    Path parent = (Path) key.watchable();
    Path p = parent.resolve((Path) event.context());
    for (DirectoryModifiedListener listener : listeners) {
        if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
            // only do this if p referred to a file, not a directory
            listener.onFileCreated(p);
        }
    }
}

我的问题是如何确定路径p是否引用已删除的文件或目录?API 公开的内容甚至可能做到这一点吗?

Files.isDirectory(path) 顾名思义,是一个实时检查。

Path

对象(分别是实现 WindowsPath)本身没有状态(或缓存的历史记录)。它只不过是路径的占位符。

因此,可悲的答案是:您无法确定 Path 在删除后是否引用了目录。

一种解决方案是记住 Path 对象的类型,只要它们存在。这意味着在开始观看之前收集一个列表:

Path parent = Paths.get("/my/hotfolder");
Set<String> subdirs = new HashSet<String>();
for (Path p : Files.newDirectoryStream(parent)) {
    if (Files.isDirectory(p))
        subdirs.add(p.getFileName().toString());
}

注册ENTRY_CREATE以使列表保持最新

WatchKey key = hotfolder.register(watcher, ENTRY_CREATE, ENTRY_DELETE);

现在,您可以确定子对象是否为目录:

for (WatchEvent<?> event : key.pollEvents())
{
    if (event.kind() == StandardWatchEventKinds.OVERFLOW)
        continue;
    Path p = ((Path) key.watchable()).resolve((Path) event.context());
    String filename = p.getFileName().toString();
    if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE && Files.isDirectory(p))
        subdirs.add(filename);
    if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE)
    {
        if (subdirs.contains(filename))
        {
            for (DirectoryModifiedListener listener : listeners)
                listener.onFileDeleted(p);
            subdirs.remove(filename);
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新