我递归地监视一个目录(以及所有子目录和文件)中的更改。
看起来,如果我在根目录的子目录中创建或删除一个目录或文件来监视路径,那么(通过context())接收到的WatchEvent实例中包含的路径没有父目录,因此rootDirToWatch.resolve(event.context())
没有返回我想要的路径。
例如:
监视/home/johannes/test
,然后在/home/johannes/test/foo/bar
中创建一个名为baz
的新目录,并获得一个名为/home/johannes/test/baz
而不是/home/johannes/test/foo/bar/baz
的新路径实例
有什么建议出了什么问题吗?
我只是简单地使用一个访问者来监视某个根目录中的所有子目录(监视整个目录及其所有后代):
@Override
public FileVisitResult preVisitDirectory(final Path pDir, final BasicFileAttributes pAttrs)
throws IOException
{
checkNotNull(pDir);
checkNotNull(pAttrs);
pDir.register(mWatcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
return FileVisitResult.CONTINUE;
}
编辑:我想我真的必须使用一个访问者,或者至少向观察者注册所有子目录。因为WatchEvent返回一个相对路径,所以很清楚为什么它会像描述的那样工作,但我不想再次遍历目录来查找从根目录到添加/删除/修改的文件在层次结构中的某个位置的路径。
编辑:我已经找到了解决方案(“索引”键):http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/io/examples/WatchDir.java
发布于 2013-11-13 10:47:18
艾伦是对的。
您应该在密钥中使用Watchable。
下面是我的应用程序中的Scala代码。我想你会看得懂的。
object FsNotifType extends Enumeration {
val Create, Update, Delete = Value
}
case class FsNotif(notifType: FsNotifType.Value,path: Path)
object FsNotif {
def apply(watchKey: WatchKey,event: java.nio.file.WatchEvent[_]): FsNotif = {
val fsNotifType = event.kind() match {
case StandardWatchEventKinds.ENTRY_CREATE => FsNotifType.Create
case StandardWatchEventKinds.ENTRY_MODIFY => FsNotifType.Update
case StandardWatchEventKinds.ENTRY_DELETE => FsNotifType.Delete
case _ => throw new IllegalStateException("Unknown FS event kind: " + event)
}
val watchedPath = watchKey.watchable().asInstanceOf[Path]
val relativePath = event.context().asInstanceOf[Path]
val absolutePath = watchedPath.resolve(relativePath)
FsNotif(fsNotifType,absolutePath)
}
}
这可以很好地工作,但要注意一些边角情况:
/**
* Returns the object for which this watch key was created. This method will
* continue to return the object even after the key is cancelled.
*
* <p> As the {@code WatchService} is intended to map directly on to the
* native file event notification facility (where available) then many of
* details on how registered objects are watched is highly implementation
* specific. When watching a directory for changes for example, and the
* directory is moved or renamed in the file system, there is no guarantee
* that the watch key will be cancelled and so the object returned by this
* method may no longer be a valid path to the directory.
*
* @return the object for which this watch key was created
*/
Watchable watchable();
对不起,我不知道怎么处理这件事。
发布于 2011-11-21 12:47:00
watchable()方法将返回原始的Watchable,因此您可以将其用作父目录。
https://stackoverflow.com/questions/8205842
复制