如何在不遵循符号链接的情况下确定文件的规范路径



假设我有以下java.io.File和相应的java.nio.file.Path对象:

final String windir = "WINNT";
final String comspec = "cmd.exe";
final File absoluteFile = new File(format("C:\./foo/../bar/../%s/./././././SYSTEM32/../system/../System32/%s", windir, comspec)).getAbsoluteFile();
final Path absolutePath = absoluteFile.toPath();

现在,我想确定规范路径,即删除任何...路径条目,这样得到的路径就是C:WINNTSystem32cmd.exe

java.io.File.getCanonicalPath()很好,只是它遵循Unices上的符号链接,我想避免这样做。

另一方面,java.nio.file.Path.toRealPath(NOFOLLOW_LINKS)返回规范路径,符号链接后面没有,但它抛出一个java.nio.file.NoSuchFileException

如何确定文件的规范路径

  • 以一种安全的方式(这样在文件不存在的情况下就不会抛出异常(
  • 以独立于平台的方式,以及
  • 没有遵循符号链接

到目前为止,我找到的唯一解决方案是回到旧的java.ioAPI:

@NonNull Path toCanonicalPath(final @NonNull Path path) throws IOException {
try {
/*
* Fails for nonexistent files.
*/
return path.toRealPath(NOFOLLOW_LINKS);
} catch (final NoSuchFileException ignored) {
/*
* This one is fine except it always follows symbolic links on Unices.
*/
return path.toFile().getCanonicalFile().toPath();
} catch (final FileSystemException ignored) {
/*
* Thrown when there's a file/directory conflict, e. g.
* for a non-existent file "foo/bar", "foo" already
* exists and is a symlink, not a directory. In this
* case, we can't use the File#getCanonicalFile() call.
*/
return path.toAbsolutePath();
}
}

还有什么不那么丑陋的方法吗?

path.toAbsolutePath().normalize()实际上做到了。

假设我们有一个指向/var/mail:的/var/spool/mail符号链接

final Path path = Paths.get("/var/./spool/../spool//mail/./");
System.out.println(path.toAbsolutePath().normalize());
System.out.println(path.toRealPath(NOFOLLOW_LINKS));

在上面的例子中,在这两种情况下,规范路径都打印有未解决的符号链接:

/var/spool/mail
/var/spool/mail

最新更新