Difference between getCanonicalPath and toRealPath












5















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?










share|improve this question























  • 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
















5















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?










share|improve this question























  • 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














5












5








5








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?










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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



















  • 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












5 Answers
5






active

oldest

votes


















1














Conclusions:





  • getAboslutePath and getPath never fail as they don't do validation


  • getCanonicalPath reach invalid results when drive letter from url is invalid or different than the current folder

  • toPath().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)





share|improve this answer

































    3














    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.






    share|improve this answer



















    • 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



















    2














    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





    share|improve this answer
























    • I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()

      – Johsm
      Jun 23 '15 at 7:50



















    1














    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.






    share|improve this answer































      0














      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.






      share|improve this answer
























      • 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











      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
      });


      }
      });














      draft saved

      draft discarded


















      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









      1














      Conclusions:





      • getAboslutePath and getPath never fail as they don't do validation


      • getCanonicalPath reach invalid results when drive letter from url is invalid or different than the current folder

      • toPath().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)





      share|improve this answer






























        1














        Conclusions:





        • getAboslutePath and getPath never fail as they don't do validation


        • getCanonicalPath reach invalid results when drive letter from url is invalid or different than the current folder

        • toPath().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)





        share|improve this answer




























          1












          1








          1







          Conclusions:





          • getAboslutePath and getPath never fail as they don't do validation


          • getCanonicalPath reach invalid results when drive letter from url is invalid or different than the current folder

          • toPath().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)





          share|improve this answer















          Conclusions:





          • getAboslutePath and getPath never fail as they don't do validation


          • getCanonicalPath reach invalid results when drive letter from url is invalid or different than the current folder

          • toPath().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)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 19 at 23:27

























          answered Dec 27 '18 at 20:01









          raisercostinraisercostin

          5,04034356




          5,04034356

























              3














              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.






              share|improve this answer



















              • 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
















              3














              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.






              share|improve this answer



















              • 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














              3












              3








              3







              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.






              share|improve this answer













              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.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              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














              • 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











              2














              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





              share|improve this answer
























              • I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()

                – Johsm
                Jun 23 '15 at 7:50
















              2














              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





              share|improve this answer
























              • I was innterested in Path.toRealPath() which seems to do something very similar to File.getCanonicalPath()

                – Johsm
                Jun 23 '15 at 7:50














              2












              2








              2







              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





              share|improve this answer













              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






              share|improve this answer












              share|improve this answer



              share|improve this answer










              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



















              • 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











              1














              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.






              share|improve this answer




























                1














                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.






                share|improve this answer


























                  1












                  1








                  1







                  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.






                  share|improve this answer













                  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.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Apr 25 '16 at 14:04









                  anreanre

                  2,7952029




                  2,7952029























                      0














                      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.






                      share|improve this answer
























                      • 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
















                      0














                      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.






                      share|improve this answer
























                      • 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














                      0












                      0








                      0







                      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.






                      share|improve this answer













                      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.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      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



















                      • 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


















                      draft saved

                      draft discarded




















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      Callistus III

                      Plistias Cous

                      Index Sanctorum