如何在不遵循符号链接的情况下确定文件的规范路径?
How can I determine the canonical path of a file without following symbolic links?
假设我有以下 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();
现在,我想确定规范路径,我。 e.删除任何 .
或 ..
路径条目,以便生成的路径为 C:\WINNT\System32\cmd.exe
.
java.io.File.getCanonicalPath()
很好,除了它遵循我想避免的 Unices 上的符号链接。
java.nio.file.Path.toRealPath(NOFOLLOW_LINKS)
,另一方面,returns 规范路径 没有 跟随符号链接,但它抛出 java.nio.file.NoSuchFileException
.
如何确定文件的规范路径
- 以安全的方式(以便在文件不存在的情况下不会抛出异常),
- 以独立于平台的方式,并且
- 没有跟随符号链接?
到目前为止我找到的唯一解决方案是回到旧的 java.io
API:
@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/spool/mail
符号链接指向 /var/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
假设我有以下 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();
现在,我想确定规范路径,我。 e.删除任何 .
或 ..
路径条目,以便生成的路径为 C:\WINNT\System32\cmd.exe
.
java.io.File.getCanonicalPath()
很好,除了它遵循我想避免的 Unices 上的符号链接。
java.nio.file.Path.toRealPath(NOFOLLOW_LINKS)
,另一方面,returns 规范路径 没有 跟随符号链接,但它抛出 java.nio.file.NoSuchFileException
.
如何确定文件的规范路径
- 以安全的方式(以便在文件不存在的情况下不会抛出异常),
- 以独立于平台的方式,并且
- 没有跟随符号链接?
到目前为止我找到的唯一解决方案是回到旧的 java.io
API:
@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/spool/mail
符号链接指向 /var/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