Assume I have the following java.io.File
and the corresponding java.nio.file.Path
objects:
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();
Now, I want to determine the canonical path, i. e. remove any .
or ..
path entries, so that the resulting path is C:\WINNT\System32\cmd.exe
.
java.io.File.getCanonicalPath()
is fine, except that it follows symbolic links on Unices which I would like to avoid.
java.nio.file.Path.toRealPath(NOFOLLOW_LINKS)
, on the other hand, returns the canonical path without following symbolic links, but it throws a java.nio.file.NoSuchFileException
.
How can I determine the canonical path of a file
The only solution I have found so far is falling back to the old 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();
}
}
Is there any less ugly approach?
path.toAbsolutePath().normalize()
actually did the trick.
Consider we have a /var/spool/mail
symlink pointing to /var/mail
:
final Path path = Paths.get("/var/./spool/../spool//mail/./");
System.out.println(path.toAbsolutePath().normalize());
System.out.println(path.toRealPath(NOFOLLOW_LINKS));
In the above example, in both cases the canonical path is printed with symlinks left unresolved:
/var/spool/mail
/var/spool/mail
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With