efr*_*itz 5 java io nio watchservice
我有一个WatchService监视目录树的ENTRY_CREATE, ENTRY_DELETEANDENTRY-MODIFY事件。问题是 a 的上下文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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何确定路径是否p引用了已删除的文件或目录?通过 API 公开的内容是否可以实现这一点?
Files.isDirectory(path) - 顾名思义 - 是实时检查。
Path 对象(分别是 WindowsPath 的实现)本身没有状态(或缓存的历史记录)。它只不过是路径的占位符。
因此,悲伤的答案是:您无法确定路径在删除后是否引用了目录。
一种解决方案是记住 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());
}
Run Code Online (Sandbox Code Playgroud)
注册 ENTRY_CREATE 以使列表保持最新
WatchKey key = hotfolder.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
Run Code Online (Sandbox Code Playgroud)
现在您可以确定子对象是否是目录:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1324 次 |
| 最近记录: |