Difference between getCanonicalPath and toRealPath
Are there cases where File.getCanonicalPath() and File.toPath().toRealPath() will produce different results?
They seem to do both rather similar things but the documentation never atually states that they are supposed to do the same thing.
Are there border cases where I would to prefer one method over the other?
And how about File.getAbsolutePath() versus Path.toAbsolutePath() - are they supposed to work in the same way?
java nio
add a comment |
Are there cases where File.getCanonicalPath() and File.toPath().toRealPath() will produce different results?
They seem to do both rather similar things but the documentation never atually states that they are supposed to do the same thing.
Are there border cases where I would to prefer one method over the other?
And how about File.getAbsolutePath() versus Path.toAbsolutePath() - are they supposed to work in the same way?
java nio
See stackoverflow.com/questions/1099300/…
– Lucas Holt
Jun 18 '15 at 16:23
1
@LucasHolt: That's talking about a completely different API. This is Java.NIO.
– Makoto
Jun 18 '15 at 16:24
Yes, but the way paths are handled are the same.
– Lucas Holt
Jun 18 '15 at 16:25
There are nuances and subtleties that supersede what a path is. One of these methods actually dictates how a path is handled.
– Makoto
Jun 18 '15 at 16:28
add a comment |
Are there cases where File.getCanonicalPath() and File.toPath().toRealPath() will produce different results?
They seem to do both rather similar things but the documentation never atually states that they are supposed to do the same thing.
Are there border cases where I would to prefer one method over the other?
And how about File.getAbsolutePath() versus Path.toAbsolutePath() - are they supposed to work in the same way?
java nio
Are there cases where File.getCanonicalPath() and File.toPath().toRealPath() will produce different results?
They seem to do both rather similar things but the documentation never atually states that they are supposed to do the same thing.
Are there border cases where I would to prefer one method over the other?
And how about File.getAbsolutePath() versus Path.toAbsolutePath() - are they supposed to work in the same way?
java nio
java nio
asked Jun 18 '15 at 16:14
JohsmJohsm
536728
536728
See stackoverflow.com/questions/1099300/…
– Lucas Holt
Jun 18 '15 at 16:23
1
@LucasHolt: That's talking about a completely different API. This is Java.NIO.
– Makoto
Jun 18 '15 at 16:24
Yes, but the way paths are handled are the same.
– Lucas Holt
Jun 18 '15 at 16:25
There are nuances and subtleties that supersede what a path is. One of these methods actually dictates how a path is handled.
– Makoto
Jun 18 '15 at 16:28
add a comment |
See stackoverflow.com/questions/1099300/…
– Lucas Holt
Jun 18 '15 at 16:23
1
@LucasHolt: That's talking about a completely different API. This is Java.NIO.
– Makoto
Jun 18 '15 at 16:24
Yes, but the way paths are handled are the same.
– Lucas Holt
Jun 18 '15 at 16:25
There are nuances and subtleties that supersede what a path is. One of these methods actually dictates how a path is handled.
– Makoto
Jun 18 '15 at 16:28
See stackoverflow.com/questions/1099300/…
– Lucas Holt
Jun 18 '15 at 16:23
See stackoverflow.com/questions/1099300/…
– Lucas Holt
Jun 18 '15 at 16:23
1
1
@LucasHolt: That's talking about a completely different API. This is Java.NIO.
– Makoto
Jun 18 '15 at 16:24
@LucasHolt: That's talking about a completely different API. This is Java.NIO.
– Makoto
Jun 18 '15 at 16:24
Yes, but the way paths are handled are the same.
– Lucas Holt
Jun 18 '15 at 16:25
Yes, but the way paths are handled are the same.
– Lucas Holt
Jun 18 '15 at 16:25
There are nuances and subtleties that supersede what a path is. One of these methods actually dictates how a path is handled.
– Makoto
Jun 18 '15 at 16:28
There are nuances and subtleties that supersede what a path is. One of these methods actually dictates how a path is handled.
– Makoto
Jun 18 '15 at 16:28
add a comment |
5 Answers
5
active
oldest
votes
Conclusions:
getAboslutePathandgetPathnever fail as they don't do validation
getCanonicalPathreach invalid results when drive letter from url is invalid or different than the current foldertoPath().toRealPath()is checking the validity but the file needs to exist and can also follow or not follow symbolic links
toPath()is safe enough and doesn't need the file to exist..toPath().toAbsolutePath().normalize()is the best one without the need for file to exist
I did a similar test of @John in windows
@Test
public void testCanonical() throws IOException {
test("d:tarGet\..\Target", "File exist and drive letter is on the current one");
test("d:tarGet\..\Target\.\..\", "File exist and drive letter is on the current one, but parent of current drive should exist");
test("d:tarGet\non-existent\..\..\Target\.\..\", "Relative path contains non-existent file");
test("d:target\\file", "Double slash");
test("c:tarGet\..\Target\.", "File doesn't exist and drive letter is on different drive than the current one");
test("l:tarGet\..\Target\.\..\", "Drive letter doesn't exist");
test("za:tarGet\..\Target\.\..\", "Drive letter is double so not valid");
test("d:tarGet|Suffix", "Path contains invalid chars in windows (|)");
test("d:tarGetu0000Suffix", "Path contains invalid chars in both linux and windows (\0)");
}
private void test(String filename, String message) throws IOException {
java.io.File file = new java.io.File(filename);
System.out.println("Use: " + filename + " -> " + message);
System.out.println("F-GET: " + Try.of(() -> file.getPath()));
System.out.println("F-ABS: " + Try.of(() -> file.getAbsolutePath()));
System.out.println("F-CAN: " + Try.of(() -> file.getCanonicalPath()));
System.out.println("P-TO: " + Try.of(() -> file.toPath()));
System.out.println("P-ABS: " + Try.of(() -> file.toPath().toAbsolutePath()));
System.out.println("P-NOR: " + Try.of(() -> file.toPath().normalize()));
System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
System.out.println("P-REAL: " + Try.of(() -> file.toPath().toRealPath()));
System.out.println("");
}
The results are:
Use: d:tarGet..Target -> File exist and drive letter is on the current one
F-GET: Success(d:tarGet..Target)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target)
F-CAN: Success(D:homeraiserworkrestfstarget)
P-TO: Success(d:tarGet..Target)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:homeraiserworkrestfsTarget)
P-ABS-NOR: Success(D:homeraiserworkrestfsTarget)
P-REAL: Success(D:homeraiserworkrestfstarget)
Use: d:tarGet..Target... -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET: Success(d:tarGet..Target...)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGet..Target...)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:tarGetnon-existent....Target... -> Relative path contains non-existent file
F-GET: Success(d:tarGetnon-existent....Target...)
F-ABS: Success(d:homeraiserworkrestfstarGetnon-existent....Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGetnon-existent....Target...)
P-ABS: Success(D:homeraiserworkrestfstarGetnon-existent....Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:target\file -> Double slash
F-GET: Success(d:targetfile)
F-ABS: Success(d:homeraiserworkrestfstargetfile)
F-CAN: Success(D:homeraiserworkrestfstargetfile)
P-TO: Success(d:targetfile)
P-ABS: Success(D:homeraiserworkrestfstargetfile)
P-NOR: Success(d:targetfile)
P-NOR-ABS: Success(D:homeraiserworkrestfstargetfile)
P-ABS-NOR: Success(D:homeraiserworkrestfstargetfile)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:homeraiserworkrestfstargetfile)
Use: c:tarGet..Target. -> File doesn't exist and drive letter is on different drive than the current one
F-GET: Success(c:tarGet..Target.)
F-ABS: Success(c:\tarGet..Target.)
F-CAN: Success(C:Target)
P-TO: Success(c:tarGet..Target.)
P-ABS: Success(C:tarGet..Target.)
P-NOR: Success(c:Target)
P-NOR-ABS: Success(C:Target)
P-ABS-NOR: Success(C:Target)
P-REAL: Failure(java.nio.file.NoSuchFileException: C:Target)
Use: l:tarGet..Target... -> Drive letter doesn't exist
F-GET: Success(l:tarGet..Target...)
F-ABS: Success(l:tarGet..Target...)
F-CAN: Success(L:)
P-TO: Success(l:tarGet..Target...)
P-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR: Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL: Failure(java.io.IOException: Unable to get working directory of drive 'L')
Use: za:tarGet..Target... -> Drive letter is double so not valid
F-GET: Success(za:tarGet..Target...)
F-ABS: Success(D:homeraiserworkrestfsza:tarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
Use: d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET: Success(d:tarGet|Suffix)
F-ABS: Success(d:homeraiserworkrestfstarGet|Suffix)
F-CAN: Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
add a comment |
A canonical path is absolute and unique, but will have different meaning on different systems.
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent.
A real path is the actual path with respect to the system. You would also have to pass in whether or not you don't deal with symbolic links, where it's implicitly handled with canonicalPath.
The precise definition of this method is implementation dependent but in general it derives from this path, an absolute path that locates the same file as this path, but with name elements that represent the actual name of the directories and the file. For example, where filename comparisons on a file system are case insensitive then the name elements represent the names in their actual case. Additionally, the resulting path has redundant name elements removed.
So yes, these two methods can return different things, but it really depends on your system. If you need something that's unique, then canonicalPath is your safest bet, even if it's not a Path.
1
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
add a comment |
Sure, the example below shows some of the differences. Also getCanonicalPath will throw an exception if the file does not exist.
getCanonicalPath returns the path in its canonical or simplest form (from http://www.merriam-webster.com/dictionary/canonical%20form)
import java.io.File;
public class FileExample {
public static void main(String args) throws Exception {
File file = new File("/TEMP/../TEMP/myfile.txt");
System.out.println("ABS: " + file.getAbsolutePath());
System.out.println(" TO: " + file.toPath());
System.out.println("GET: " + file.getPath());
System.out.println("CAN: " + file.getCanonicalPath());
}
}
ABS: C:TEMP..TEMPmyfile.txt
TO: TEMP..TEMPmyfile.txt
GET: TEMP..TEMPmyfile.txt
CAN: C:TEMPmyfile.txt
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
add a comment |
What I noticed from my tests is that
Path.toRealPath() will throw java.nio.file.NoSuchFileException if the file does not exist (Javadoc: Returns the real path of an existing file.)
File.getCanonicalPath() will not throw an exception if the file does not exist (it will only throw IOException if
the file name itself is invalid and contains a '' char in it).
So the former would not be suitable if you want to use it for path checks before actually creating the file.
You are right that the Javadoc for both methods is somewhat shallow.
add a comment |
The API states that the canonical path usually removes redundancies and resolves symbolic links and so on.
Try the following on a UNIX machine:
File file = new File("../test.txt"); // execute from /tmp/java/example
file.getAbsolutePath(); // evaluates to /tmp/java/example/../test.txt
file.getCanonicalPath(); // evaluates to /tmp/java/test.txt
The difference between File and Path is that Path is part of the newer NIO API which has many improvements and is more flexible.
As an example you could exchange the implementation of the file system with NIO (see https://github.com/google/jimfs), whereas java.io.File forces you to operate on your host file system.
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f30920623%2fdifference-between-getcanonicalpath-and-torealpath%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Conclusions:
getAboslutePathandgetPathnever fail as they don't do validation
getCanonicalPathreach invalid results when drive letter from url is invalid or different than the current foldertoPath().toRealPath()is checking the validity but the file needs to exist and can also follow or not follow symbolic links
toPath()is safe enough and doesn't need the file to exist..toPath().toAbsolutePath().normalize()is the best one without the need for file to exist
I did a similar test of @John in windows
@Test
public void testCanonical() throws IOException {
test("d:tarGet\..\Target", "File exist and drive letter is on the current one");
test("d:tarGet\..\Target\.\..\", "File exist and drive letter is on the current one, but parent of current drive should exist");
test("d:tarGet\non-existent\..\..\Target\.\..\", "Relative path contains non-existent file");
test("d:target\\file", "Double slash");
test("c:tarGet\..\Target\.", "File doesn't exist and drive letter is on different drive than the current one");
test("l:tarGet\..\Target\.\..\", "Drive letter doesn't exist");
test("za:tarGet\..\Target\.\..\", "Drive letter is double so not valid");
test("d:tarGet|Suffix", "Path contains invalid chars in windows (|)");
test("d:tarGetu0000Suffix", "Path contains invalid chars in both linux and windows (\0)");
}
private void test(String filename, String message) throws IOException {
java.io.File file = new java.io.File(filename);
System.out.println("Use: " + filename + " -> " + message);
System.out.println("F-GET: " + Try.of(() -> file.getPath()));
System.out.println("F-ABS: " + Try.of(() -> file.getAbsolutePath()));
System.out.println("F-CAN: " + Try.of(() -> file.getCanonicalPath()));
System.out.println("P-TO: " + Try.of(() -> file.toPath()));
System.out.println("P-ABS: " + Try.of(() -> file.toPath().toAbsolutePath()));
System.out.println("P-NOR: " + Try.of(() -> file.toPath().normalize()));
System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
System.out.println("P-REAL: " + Try.of(() -> file.toPath().toRealPath()));
System.out.println("");
}
The results are:
Use: d:tarGet..Target -> File exist and drive letter is on the current one
F-GET: Success(d:tarGet..Target)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target)
F-CAN: Success(D:homeraiserworkrestfstarget)
P-TO: Success(d:tarGet..Target)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:homeraiserworkrestfsTarget)
P-ABS-NOR: Success(D:homeraiserworkrestfsTarget)
P-REAL: Success(D:homeraiserworkrestfstarget)
Use: d:tarGet..Target... -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET: Success(d:tarGet..Target...)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGet..Target...)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:tarGetnon-existent....Target... -> Relative path contains non-existent file
F-GET: Success(d:tarGetnon-existent....Target...)
F-ABS: Success(d:homeraiserworkrestfstarGetnon-existent....Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGetnon-existent....Target...)
P-ABS: Success(D:homeraiserworkrestfstarGetnon-existent....Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:target\file -> Double slash
F-GET: Success(d:targetfile)
F-ABS: Success(d:homeraiserworkrestfstargetfile)
F-CAN: Success(D:homeraiserworkrestfstargetfile)
P-TO: Success(d:targetfile)
P-ABS: Success(D:homeraiserworkrestfstargetfile)
P-NOR: Success(d:targetfile)
P-NOR-ABS: Success(D:homeraiserworkrestfstargetfile)
P-ABS-NOR: Success(D:homeraiserworkrestfstargetfile)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:homeraiserworkrestfstargetfile)
Use: c:tarGet..Target. -> File doesn't exist and drive letter is on different drive than the current one
F-GET: Success(c:tarGet..Target.)
F-ABS: Success(c:\tarGet..Target.)
F-CAN: Success(C:Target)
P-TO: Success(c:tarGet..Target.)
P-ABS: Success(C:tarGet..Target.)
P-NOR: Success(c:Target)
P-NOR-ABS: Success(C:Target)
P-ABS-NOR: Success(C:Target)
P-REAL: Failure(java.nio.file.NoSuchFileException: C:Target)
Use: l:tarGet..Target... -> Drive letter doesn't exist
F-GET: Success(l:tarGet..Target...)
F-ABS: Success(l:tarGet..Target...)
F-CAN: Success(L:)
P-TO: Success(l:tarGet..Target...)
P-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR: Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL: Failure(java.io.IOException: Unable to get working directory of drive 'L')
Use: za:tarGet..Target... -> Drive letter is double so not valid
F-GET: Success(za:tarGet..Target...)
F-ABS: Success(D:homeraiserworkrestfsza:tarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
Use: d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET: Success(d:tarGet|Suffix)
F-ABS: Success(d:homeraiserworkrestfstarGet|Suffix)
F-CAN: Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
add a comment |
Conclusions:
getAboslutePathandgetPathnever fail as they don't do validation
getCanonicalPathreach invalid results when drive letter from url is invalid or different than the current foldertoPath().toRealPath()is checking the validity but the file needs to exist and can also follow or not follow symbolic links
toPath()is safe enough and doesn't need the file to exist..toPath().toAbsolutePath().normalize()is the best one without the need for file to exist
I did a similar test of @John in windows
@Test
public void testCanonical() throws IOException {
test("d:tarGet\..\Target", "File exist and drive letter is on the current one");
test("d:tarGet\..\Target\.\..\", "File exist and drive letter is on the current one, but parent of current drive should exist");
test("d:tarGet\non-existent\..\..\Target\.\..\", "Relative path contains non-existent file");
test("d:target\\file", "Double slash");
test("c:tarGet\..\Target\.", "File doesn't exist and drive letter is on different drive than the current one");
test("l:tarGet\..\Target\.\..\", "Drive letter doesn't exist");
test("za:tarGet\..\Target\.\..\", "Drive letter is double so not valid");
test("d:tarGet|Suffix", "Path contains invalid chars in windows (|)");
test("d:tarGetu0000Suffix", "Path contains invalid chars in both linux and windows (\0)");
}
private void test(String filename, String message) throws IOException {
java.io.File file = new java.io.File(filename);
System.out.println("Use: " + filename + " -> " + message);
System.out.println("F-GET: " + Try.of(() -> file.getPath()));
System.out.println("F-ABS: " + Try.of(() -> file.getAbsolutePath()));
System.out.println("F-CAN: " + Try.of(() -> file.getCanonicalPath()));
System.out.println("P-TO: " + Try.of(() -> file.toPath()));
System.out.println("P-ABS: " + Try.of(() -> file.toPath().toAbsolutePath()));
System.out.println("P-NOR: " + Try.of(() -> file.toPath().normalize()));
System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
System.out.println("P-REAL: " + Try.of(() -> file.toPath().toRealPath()));
System.out.println("");
}
The results are:
Use: d:tarGet..Target -> File exist and drive letter is on the current one
F-GET: Success(d:tarGet..Target)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target)
F-CAN: Success(D:homeraiserworkrestfstarget)
P-TO: Success(d:tarGet..Target)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:homeraiserworkrestfsTarget)
P-ABS-NOR: Success(D:homeraiserworkrestfsTarget)
P-REAL: Success(D:homeraiserworkrestfstarget)
Use: d:tarGet..Target... -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET: Success(d:tarGet..Target...)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGet..Target...)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:tarGetnon-existent....Target... -> Relative path contains non-existent file
F-GET: Success(d:tarGetnon-existent....Target...)
F-ABS: Success(d:homeraiserworkrestfstarGetnon-existent....Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGetnon-existent....Target...)
P-ABS: Success(D:homeraiserworkrestfstarGetnon-existent....Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:target\file -> Double slash
F-GET: Success(d:targetfile)
F-ABS: Success(d:homeraiserworkrestfstargetfile)
F-CAN: Success(D:homeraiserworkrestfstargetfile)
P-TO: Success(d:targetfile)
P-ABS: Success(D:homeraiserworkrestfstargetfile)
P-NOR: Success(d:targetfile)
P-NOR-ABS: Success(D:homeraiserworkrestfstargetfile)
P-ABS-NOR: Success(D:homeraiserworkrestfstargetfile)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:homeraiserworkrestfstargetfile)
Use: c:tarGet..Target. -> File doesn't exist and drive letter is on different drive than the current one
F-GET: Success(c:tarGet..Target.)
F-ABS: Success(c:\tarGet..Target.)
F-CAN: Success(C:Target)
P-TO: Success(c:tarGet..Target.)
P-ABS: Success(C:tarGet..Target.)
P-NOR: Success(c:Target)
P-NOR-ABS: Success(C:Target)
P-ABS-NOR: Success(C:Target)
P-REAL: Failure(java.nio.file.NoSuchFileException: C:Target)
Use: l:tarGet..Target... -> Drive letter doesn't exist
F-GET: Success(l:tarGet..Target...)
F-ABS: Success(l:tarGet..Target...)
F-CAN: Success(L:)
P-TO: Success(l:tarGet..Target...)
P-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR: Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL: Failure(java.io.IOException: Unable to get working directory of drive 'L')
Use: za:tarGet..Target... -> Drive letter is double so not valid
F-GET: Success(za:tarGet..Target...)
F-ABS: Success(D:homeraiserworkrestfsza:tarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
Use: d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET: Success(d:tarGet|Suffix)
F-ABS: Success(d:homeraiserworkrestfstarGet|Suffix)
F-CAN: Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
add a comment |
Conclusions:
getAboslutePathandgetPathnever fail as they don't do validation
getCanonicalPathreach invalid results when drive letter from url is invalid or different than the current foldertoPath().toRealPath()is checking the validity but the file needs to exist and can also follow or not follow symbolic links
toPath()is safe enough and doesn't need the file to exist..toPath().toAbsolutePath().normalize()is the best one without the need for file to exist
I did a similar test of @John in windows
@Test
public void testCanonical() throws IOException {
test("d:tarGet\..\Target", "File exist and drive letter is on the current one");
test("d:tarGet\..\Target\.\..\", "File exist and drive letter is on the current one, but parent of current drive should exist");
test("d:tarGet\non-existent\..\..\Target\.\..\", "Relative path contains non-existent file");
test("d:target\\file", "Double slash");
test("c:tarGet\..\Target\.", "File doesn't exist and drive letter is on different drive than the current one");
test("l:tarGet\..\Target\.\..\", "Drive letter doesn't exist");
test("za:tarGet\..\Target\.\..\", "Drive letter is double so not valid");
test("d:tarGet|Suffix", "Path contains invalid chars in windows (|)");
test("d:tarGetu0000Suffix", "Path contains invalid chars in both linux and windows (\0)");
}
private void test(String filename, String message) throws IOException {
java.io.File file = new java.io.File(filename);
System.out.println("Use: " + filename + " -> " + message);
System.out.println("F-GET: " + Try.of(() -> file.getPath()));
System.out.println("F-ABS: " + Try.of(() -> file.getAbsolutePath()));
System.out.println("F-CAN: " + Try.of(() -> file.getCanonicalPath()));
System.out.println("P-TO: " + Try.of(() -> file.toPath()));
System.out.println("P-ABS: " + Try.of(() -> file.toPath().toAbsolutePath()));
System.out.println("P-NOR: " + Try.of(() -> file.toPath().normalize()));
System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
System.out.println("P-REAL: " + Try.of(() -> file.toPath().toRealPath()));
System.out.println("");
}
The results are:
Use: d:tarGet..Target -> File exist and drive letter is on the current one
F-GET: Success(d:tarGet..Target)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target)
F-CAN: Success(D:homeraiserworkrestfstarget)
P-TO: Success(d:tarGet..Target)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:homeraiserworkrestfsTarget)
P-ABS-NOR: Success(D:homeraiserworkrestfsTarget)
P-REAL: Success(D:homeraiserworkrestfstarget)
Use: d:tarGet..Target... -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET: Success(d:tarGet..Target...)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGet..Target...)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:tarGetnon-existent....Target... -> Relative path contains non-existent file
F-GET: Success(d:tarGetnon-existent....Target...)
F-ABS: Success(d:homeraiserworkrestfstarGetnon-existent....Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGetnon-existent....Target...)
P-ABS: Success(D:homeraiserworkrestfstarGetnon-existent....Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:target\file -> Double slash
F-GET: Success(d:targetfile)
F-ABS: Success(d:homeraiserworkrestfstargetfile)
F-CAN: Success(D:homeraiserworkrestfstargetfile)
P-TO: Success(d:targetfile)
P-ABS: Success(D:homeraiserworkrestfstargetfile)
P-NOR: Success(d:targetfile)
P-NOR-ABS: Success(D:homeraiserworkrestfstargetfile)
P-ABS-NOR: Success(D:homeraiserworkrestfstargetfile)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:homeraiserworkrestfstargetfile)
Use: c:tarGet..Target. -> File doesn't exist and drive letter is on different drive than the current one
F-GET: Success(c:tarGet..Target.)
F-ABS: Success(c:\tarGet..Target.)
F-CAN: Success(C:Target)
P-TO: Success(c:tarGet..Target.)
P-ABS: Success(C:tarGet..Target.)
P-NOR: Success(c:Target)
P-NOR-ABS: Success(C:Target)
P-ABS-NOR: Success(C:Target)
P-REAL: Failure(java.nio.file.NoSuchFileException: C:Target)
Use: l:tarGet..Target... -> Drive letter doesn't exist
F-GET: Success(l:tarGet..Target...)
F-ABS: Success(l:tarGet..Target...)
F-CAN: Success(L:)
P-TO: Success(l:tarGet..Target...)
P-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR: Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL: Failure(java.io.IOException: Unable to get working directory of drive 'L')
Use: za:tarGet..Target... -> Drive letter is double so not valid
F-GET: Success(za:tarGet..Target...)
F-ABS: Success(D:homeraiserworkrestfsza:tarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
Use: d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET: Success(d:tarGet|Suffix)
F-ABS: Success(d:homeraiserworkrestfstarGet|Suffix)
F-CAN: Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
Conclusions:
getAboslutePathandgetPathnever fail as they don't do validation
getCanonicalPathreach invalid results when drive letter from url is invalid or different than the current foldertoPath().toRealPath()is checking the validity but the file needs to exist and can also follow or not follow symbolic links
toPath()is safe enough and doesn't need the file to exist..toPath().toAbsolutePath().normalize()is the best one without the need for file to exist
I did a similar test of @John in windows
@Test
public void testCanonical() throws IOException {
test("d:tarGet\..\Target", "File exist and drive letter is on the current one");
test("d:tarGet\..\Target\.\..\", "File exist and drive letter is on the current one, but parent of current drive should exist");
test("d:tarGet\non-existent\..\..\Target\.\..\", "Relative path contains non-existent file");
test("d:target\\file", "Double slash");
test("c:tarGet\..\Target\.", "File doesn't exist and drive letter is on different drive than the current one");
test("l:tarGet\..\Target\.\..\", "Drive letter doesn't exist");
test("za:tarGet\..\Target\.\..\", "Drive letter is double so not valid");
test("d:tarGet|Suffix", "Path contains invalid chars in windows (|)");
test("d:tarGetu0000Suffix", "Path contains invalid chars in both linux and windows (\0)");
}
private void test(String filename, String message) throws IOException {
java.io.File file = new java.io.File(filename);
System.out.println("Use: " + filename + " -> " + message);
System.out.println("F-GET: " + Try.of(() -> file.getPath()));
System.out.println("F-ABS: " + Try.of(() -> file.getAbsolutePath()));
System.out.println("F-CAN: " + Try.of(() -> file.getCanonicalPath()));
System.out.println("P-TO: " + Try.of(() -> file.toPath()));
System.out.println("P-ABS: " + Try.of(() -> file.toPath().toAbsolutePath()));
System.out.println("P-NOR: " + Try.of(() -> file.toPath().normalize()));
System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
System.out.println("P-REAL: " + Try.of(() -> file.toPath().toRealPath()));
System.out.println("");
}
The results are:
Use: d:tarGet..Target -> File exist and drive letter is on the current one
F-GET: Success(d:tarGet..Target)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target)
F-CAN: Success(D:homeraiserworkrestfstarget)
P-TO: Success(d:tarGet..Target)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target)
P-NOR: Success(d:Target)
P-NOR-ABS: Success(D:homeraiserworkrestfsTarget)
P-ABS-NOR: Success(D:homeraiserworkrestfsTarget)
P-REAL: Success(D:homeraiserworkrestfstarget)
Use: d:tarGet..Target... -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET: Success(d:tarGet..Target...)
F-ABS: Success(d:homeraiserworkrestfstarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGet..Target...)
P-ABS: Success(D:homeraiserworkrestfstarGet..Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:tarGetnon-existent....Target... -> Relative path contains non-existent file
F-GET: Success(d:tarGetnon-existent....Target...)
F-ABS: Success(d:homeraiserworkrestfstarGetnon-existent....Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Success(d:tarGetnon-existent....Target...)
P-ABS: Success(D:homeraiserworkrestfstarGetnon-existent....Target...)
P-NOR: Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL: Success(D:homeraiserworkrestfs)
Use: d:target\file -> Double slash
F-GET: Success(d:targetfile)
F-ABS: Success(d:homeraiserworkrestfstargetfile)
F-CAN: Success(D:homeraiserworkrestfstargetfile)
P-TO: Success(d:targetfile)
P-ABS: Success(D:homeraiserworkrestfstargetfile)
P-NOR: Success(d:targetfile)
P-NOR-ABS: Success(D:homeraiserworkrestfstargetfile)
P-ABS-NOR: Success(D:homeraiserworkrestfstargetfile)
P-REAL: Failure(java.nio.file.NoSuchFileException: D:homeraiserworkrestfstargetfile)
Use: c:tarGet..Target. -> File doesn't exist and drive letter is on different drive than the current one
F-GET: Success(c:tarGet..Target.)
F-ABS: Success(c:\tarGet..Target.)
F-CAN: Success(C:Target)
P-TO: Success(c:tarGet..Target.)
P-ABS: Success(C:tarGet..Target.)
P-NOR: Success(c:Target)
P-NOR-ABS: Success(C:Target)
P-ABS-NOR: Success(C:Target)
P-REAL: Failure(java.nio.file.NoSuchFileException: C:Target)
Use: l:tarGet..Target... -> Drive letter doesn't exist
F-GET: Success(l:tarGet..Target...)
F-ABS: Success(l:tarGet..Target...)
F-CAN: Success(L:)
P-TO: Success(l:tarGet..Target...)
P-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR: Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL: Failure(java.io.IOException: Unable to get working directory of drive 'L')
Use: za:tarGet..Target... -> Drive letter is double so not valid
F-GET: Success(za:tarGet..Target...)
F-ABS: Success(D:homeraiserworkrestfsza:tarGet..Target...)
F-CAN: Success(D:homeraiserworkrestfs)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
Use: d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET: Success(d:tarGet|Suffix)
F-ABS: Success(d:homeraiserworkrestfstarGet|Suffix)
F-CAN: Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
edited Jan 19 at 23:27
answered Dec 27 '18 at 20:01
raisercostinraisercostin
5,04034356
5,04034356
add a comment |
add a comment |
A canonical path is absolute and unique, but will have different meaning on different systems.
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent.
A real path is the actual path with respect to the system. You would also have to pass in whether or not you don't deal with symbolic links, where it's implicitly handled with canonicalPath.
The precise definition of this method is implementation dependent but in general it derives from this path, an absolute path that locates the same file as this path, but with name elements that represent the actual name of the directories and the file. For example, where filename comparisons on a file system are case insensitive then the name elements represent the names in their actual case. Additionally, the resulting path has redundant name elements removed.
So yes, these two methods can return different things, but it really depends on your system. If you need something that's unique, then canonicalPath is your safest bet, even if it's not a Path.
1
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
add a comment |
A canonical path is absolute and unique, but will have different meaning on different systems.
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent.
A real path is the actual path with respect to the system. You would also have to pass in whether or not you don't deal with symbolic links, where it's implicitly handled with canonicalPath.
The precise definition of this method is implementation dependent but in general it derives from this path, an absolute path that locates the same file as this path, but with name elements that represent the actual name of the directories and the file. For example, where filename comparisons on a file system are case insensitive then the name elements represent the names in their actual case. Additionally, the resulting path has redundant name elements removed.
So yes, these two methods can return different things, but it really depends on your system. If you need something that's unique, then canonicalPath is your safest bet, even if it's not a Path.
1
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
add a comment |
A canonical path is absolute and unique, but will have different meaning on different systems.
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent.
A real path is the actual path with respect to the system. You would also have to pass in whether or not you don't deal with symbolic links, where it's implicitly handled with canonicalPath.
The precise definition of this method is implementation dependent but in general it derives from this path, an absolute path that locates the same file as this path, but with name elements that represent the actual name of the directories and the file. For example, where filename comparisons on a file system are case insensitive then the name elements represent the names in their actual case. Additionally, the resulting path has redundant name elements removed.
So yes, these two methods can return different things, but it really depends on your system. If you need something that's unique, then canonicalPath is your safest bet, even if it's not a Path.
A canonical path is absolute and unique, but will have different meaning on different systems.
A canonical pathname is both absolute and unique. The precise definition of canonical form is system-dependent.
A real path is the actual path with respect to the system. You would also have to pass in whether or not you don't deal with symbolic links, where it's implicitly handled with canonicalPath.
The precise definition of this method is implementation dependent but in general it derives from this path, an absolute path that locates the same file as this path, but with name elements that represent the actual name of the directories and the file. For example, where filename comparisons on a file system are case insensitive then the name elements represent the names in their actual case. Additionally, the resulting path has redundant name elements removed.
So yes, these two methods can return different things, but it really depends on your system. If you need something that's unique, then canonicalPath is your safest bet, even if it's not a Path.
answered Jun 18 '15 at 16:27
MakotoMakoto
81.7k17127176
81.7k17127176
1
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
add a comment |
1
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
1
1
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
Yes, thanks, but those two definitions essentially both say: we will do something to your file/path to make it "real" or "canonical" but we do not really tell you exactly what and we do not even tell you if we do the same thing in both methods (assuming for the moment that we use toRealPath() with symbolic link expansion). I find that frustrating and not very professional. The documentation does not even say if the way how this works depends on just on the OS or file system or may also depend on the Java implementation.
– Johsm
Jun 23 '15 at 7:55
add a comment |
Sure, the example below shows some of the differences. Also getCanonicalPath will throw an exception if the file does not exist.
getCanonicalPath returns the path in its canonical or simplest form (from http://www.merriam-webster.com/dictionary/canonical%20form)
import java.io.File;
public class FileExample {
public static void main(String args) throws Exception {
File file = new File("/TEMP/../TEMP/myfile.txt");
System.out.println("ABS: " + file.getAbsolutePath());
System.out.println(" TO: " + file.toPath());
System.out.println("GET: " + file.getPath());
System.out.println("CAN: " + file.getCanonicalPath());
}
}
ABS: C:TEMP..TEMPmyfile.txt
TO: TEMP..TEMPmyfile.txt
GET: TEMP..TEMPmyfile.txt
CAN: C:TEMPmyfile.txt
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
add a comment |
Sure, the example below shows some of the differences. Also getCanonicalPath will throw an exception if the file does not exist.
getCanonicalPath returns the path in its canonical or simplest form (from http://www.merriam-webster.com/dictionary/canonical%20form)
import java.io.File;
public class FileExample {
public static void main(String args) throws Exception {
File file = new File("/TEMP/../TEMP/myfile.txt");
System.out.println("ABS: " + file.getAbsolutePath());
System.out.println(" TO: " + file.toPath());
System.out.println("GET: " + file.getPath());
System.out.println("CAN: " + file.getCanonicalPath());
}
}
ABS: C:TEMP..TEMPmyfile.txt
TO: TEMP..TEMPmyfile.txt
GET: TEMP..TEMPmyfile.txt
CAN: C:TEMPmyfile.txt
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
add a comment |
Sure, the example below shows some of the differences. Also getCanonicalPath will throw an exception if the file does not exist.
getCanonicalPath returns the path in its canonical or simplest form (from http://www.merriam-webster.com/dictionary/canonical%20form)
import java.io.File;
public class FileExample {
public static void main(String args) throws Exception {
File file = new File("/TEMP/../TEMP/myfile.txt");
System.out.println("ABS: " + file.getAbsolutePath());
System.out.println(" TO: " + file.toPath());
System.out.println("GET: " + file.getPath());
System.out.println("CAN: " + file.getCanonicalPath());
}
}
ABS: C:TEMP..TEMPmyfile.txt
TO: TEMP..TEMPmyfile.txt
GET: TEMP..TEMPmyfile.txt
CAN: C:TEMPmyfile.txt
Sure, the example below shows some of the differences. Also getCanonicalPath will throw an exception if the file does not exist.
getCanonicalPath returns the path in its canonical or simplest form (from http://www.merriam-webster.com/dictionary/canonical%20form)
import java.io.File;
public class FileExample {
public static void main(String args) throws Exception {
File file = new File("/TEMP/../TEMP/myfile.txt");
System.out.println("ABS: " + file.getAbsolutePath());
System.out.println(" TO: " + file.toPath());
System.out.println("GET: " + file.getPath());
System.out.println("CAN: " + file.getCanonicalPath());
}
}
ABS: C:TEMP..TEMPmyfile.txt
TO: TEMP..TEMPmyfile.txt
GET: TEMP..TEMPmyfile.txt
CAN: C:TEMPmyfile.txt
answered Jun 18 '15 at 16:25
JohnJohn
1,23621121
1,23621121
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
add a comment |
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()
– Johsm
Jun 23 '15 at 7:50
add a comment |
What I noticed from my tests is that
Path.toRealPath() will throw java.nio.file.NoSuchFileException if the file does not exist (Javadoc: Returns the real path of an existing file.)
File.getCanonicalPath() will not throw an exception if the file does not exist (it will only throw IOException if
the file name itself is invalid and contains a '' char in it).
So the former would not be suitable if you want to use it for path checks before actually creating the file.
You are right that the Javadoc for both methods is somewhat shallow.
add a comment |
What I noticed from my tests is that
Path.toRealPath() will throw java.nio.file.NoSuchFileException if the file does not exist (Javadoc: Returns the real path of an existing file.)
File.getCanonicalPath() will not throw an exception if the file does not exist (it will only throw IOException if
the file name itself is invalid and contains a '' char in it).
So the former would not be suitable if you want to use it for path checks before actually creating the file.
You are right that the Javadoc for both methods is somewhat shallow.
add a comment |
What I noticed from my tests is that
Path.toRealPath() will throw java.nio.file.NoSuchFileException if the file does not exist (Javadoc: Returns the real path of an existing file.)
File.getCanonicalPath() will not throw an exception if the file does not exist (it will only throw IOException if
the file name itself is invalid and contains a '' char in it).
So the former would not be suitable if you want to use it for path checks before actually creating the file.
You are right that the Javadoc for both methods is somewhat shallow.
What I noticed from my tests is that
Path.toRealPath() will throw java.nio.file.NoSuchFileException if the file does not exist (Javadoc: Returns the real path of an existing file.)
File.getCanonicalPath() will not throw an exception if the file does not exist (it will only throw IOException if
the file name itself is invalid and contains a '' char in it).
So the former would not be suitable if you want to use it for path checks before actually creating the file.
You are right that the Javadoc for both methods is somewhat shallow.
answered Apr 25 '16 at 14:04
anreanre
2,7952029
2,7952029
add a comment |
add a comment |
The API states that the canonical path usually removes redundancies and resolves symbolic links and so on.
Try the following on a UNIX machine:
File file = new File("../test.txt"); // execute from /tmp/java/example
file.getAbsolutePath(); // evaluates to /tmp/java/example/../test.txt
file.getCanonicalPath(); // evaluates to /tmp/java/test.txt
The difference between File and Path is that Path is part of the newer NIO API which has many improvements and is more flexible.
As an example you could exchange the implementation of the file system with NIO (see https://github.com/google/jimfs), whereas java.io.File forces you to operate on your host file system.
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
add a comment |
The API states that the canonical path usually removes redundancies and resolves symbolic links and so on.
Try the following on a UNIX machine:
File file = new File("../test.txt"); // execute from /tmp/java/example
file.getAbsolutePath(); // evaluates to /tmp/java/example/../test.txt
file.getCanonicalPath(); // evaluates to /tmp/java/test.txt
The difference between File and Path is that Path is part of the newer NIO API which has many improvements and is more flexible.
As an example you could exchange the implementation of the file system with NIO (see https://github.com/google/jimfs), whereas java.io.File forces you to operate on your host file system.
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
add a comment |
The API states that the canonical path usually removes redundancies and resolves symbolic links and so on.
Try the following on a UNIX machine:
File file = new File("../test.txt"); // execute from /tmp/java/example
file.getAbsolutePath(); // evaluates to /tmp/java/example/../test.txt
file.getCanonicalPath(); // evaluates to /tmp/java/test.txt
The difference between File and Path is that Path is part of the newer NIO API which has many improvements and is more flexible.
As an example you could exchange the implementation of the file system with NIO (see https://github.com/google/jimfs), whereas java.io.File forces you to operate on your host file system.
The API states that the canonical path usually removes redundancies and resolves symbolic links and so on.
Try the following on a UNIX machine:
File file = new File("../test.txt"); // execute from /tmp/java/example
file.getAbsolutePath(); // evaluates to /tmp/java/example/../test.txt
file.getCanonicalPath(); // evaluates to /tmp/java/test.txt
The difference between File and Path is that Path is part of the newer NIO API which has many improvements and is more flexible.
As an example you could exchange the implementation of the file system with NIO (see https://github.com/google/jimfs), whereas java.io.File forces you to operate on your host file system.
answered Jun 18 '15 at 17:15
Franz BeckerFranz Becker
59537
59537
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
add a comment |
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
I knew that my question was about Path.toRealPath() versus File.getCanonicalPath() because they seem to do very similar things.
– Johsm
Jun 23 '15 at 7:51
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f30920623%2fdifference-between-getcanonicalpath-and-torealpath%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
See stackoverflow.com/questions/1099300/…
– Lucas Holt
Jun 18 '15 at 16:23
1
@LucasHolt: That's talking about a completely different API. This is Java.NIO.
– Makoto
Jun 18 '15 at 16:24
Yes, but the way paths are handled are the same.
– Lucas Holt
Jun 18 '15 at 16:25
There are nuances and subtleties that supersede what a path is. One of these methods actually dictates how a path is handled.
– Makoto
Jun 18 '15 at 16:28