WatchService - 错误解析的绝对路径
WatchService - incorrectly resolved absolute path
我一直在研究 java.nio.file.WatchService
并注意到从 WatchEvent.context()
编辑的 Path
s return 不 return 正确 .toAbsolutePath()
。这是一个示例应用程序:
public class FsWatcher {
public static void main(String[] args) throws IOException, InterruptedException {
if (args.length != 1) {
System.err.println("Invalid number of arguments: " + args.length);
return;
}
//Run the application with absolute path like /home/<username>
final Path watchedDirectory = Paths.get(args[0]).toAbsolutePath();
final FileSystem fileSystem = FileSystems.getDefault();
final WatchService watchService = fileSystem.newWatchService();
watchedDirectory.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
while (true) {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> watchEvent : watchKey.pollEvents()) {
if (watchEvent.kind().equals(StandardWatchEventKinds.OVERFLOW)) {
continue;
}
final Path createdFile = (Path) watchEvent.context();
final Path expectedAbsolutePath = watchedDirectory.resolve(createdFile);
System.out.println("Context path: " + createdFile);
System.out.println("Context absolute path: " + createdFile.toAbsolutePath());
System.out.println("Expected absolute path: " + expectedAbsolutePath);
System.out.println("usr.dir: " + System.getProperty("user.dir"));
}
watchKey.reset();
}
}
}
示例输出:
Context path: document.txt
Context absolute path: /home/svetlin/workspaces/default/FsWatcher/document.txt
Expected absolute path: /home/svetlin/document.txt
usr.dir: /home/svetlin/workspaces/default/FsWatcher
似乎绝对路径是针对 user.dir
系统 属性 而不是用于 WatchService
注册的 Path
解析的。这是一个问题,因为当我尝试使用(例如 Files.copy()
)从 WatchEvent
编辑的路径 return 我收到一个 java.nio.file.NoSuchFileException
,这是预期的,因为没有这样的文件在这个路径。我是不是遗漏了什么或者这是 JRE 中的错误?
这不是错误,但确实令人困惑。
如果WatchEvent.context()
returns a Path
那么它是相对的:
In the case of ENTRY_CREATE, ENTRY_DELETE, and ENTRY_MODIFY events the
context is a Path that is the relative path between the directory
registered with the watch service, and the entry that is created,
deleted, or modified.
现在,如果您通过调用 toAbsolutePath()
将这样的路径转换为绝对路径,这不是相对于监视目录而是相对于默认目录发生的。
This method resolves the path in an implementation dependent manner,
typically by resolving the path against a file system default
directory. Depending on the implementation, this method may throw an
I/O error if the file system is not accessible.
因此要将路径转为绝对路径需要使用
watchedDirectory.resolve(createdFile);
我一直在研究 java.nio.file.WatchService
并注意到从 WatchEvent.context()
编辑的 Path
s return 不 return 正确 .toAbsolutePath()
。这是一个示例应用程序:
public class FsWatcher {
public static void main(String[] args) throws IOException, InterruptedException {
if (args.length != 1) {
System.err.println("Invalid number of arguments: " + args.length);
return;
}
//Run the application with absolute path like /home/<username>
final Path watchedDirectory = Paths.get(args[0]).toAbsolutePath();
final FileSystem fileSystem = FileSystems.getDefault();
final WatchService watchService = fileSystem.newWatchService();
watchedDirectory.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
while (true) {
WatchKey watchKey = watchService.take();
for (WatchEvent<?> watchEvent : watchKey.pollEvents()) {
if (watchEvent.kind().equals(StandardWatchEventKinds.OVERFLOW)) {
continue;
}
final Path createdFile = (Path) watchEvent.context();
final Path expectedAbsolutePath = watchedDirectory.resolve(createdFile);
System.out.println("Context path: " + createdFile);
System.out.println("Context absolute path: " + createdFile.toAbsolutePath());
System.out.println("Expected absolute path: " + expectedAbsolutePath);
System.out.println("usr.dir: " + System.getProperty("user.dir"));
}
watchKey.reset();
}
}
}
示例输出:
Context path: document.txt
Context absolute path: /home/svetlin/workspaces/default/FsWatcher/document.txt
Expected absolute path: /home/svetlin/document.txt
usr.dir: /home/svetlin/workspaces/default/FsWatcher
似乎绝对路径是针对 user.dir
系统 属性 而不是用于 WatchService
注册的 Path
解析的。这是一个问题,因为当我尝试使用(例如 Files.copy()
)从 WatchEvent
编辑的路径 return 我收到一个 java.nio.file.NoSuchFileException
,这是预期的,因为没有这样的文件在这个路径。我是不是遗漏了什么或者这是 JRE 中的错误?
这不是错误,但确实令人困惑。
如果WatchEvent.context()
returns a Path
那么它是相对的:
In the case of ENTRY_CREATE, ENTRY_DELETE, and ENTRY_MODIFY events the context is a Path that is the relative path between the directory registered with the watch service, and the entry that is created, deleted, or modified.
现在,如果您通过调用 toAbsolutePath()
将这样的路径转换为绝对路径,这不是相对于监视目录而是相对于默认目录发生的。
This method resolves the path in an implementation dependent manner, typically by resolving the path against a file system default directory. Depending on the implementation, this method may throw an I/O error if the file system is not accessible.
因此要将路径转为绝对路径需要使用
watchedDirectory.resolve(createdFile);