Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a path between two paths in Java using the Path class

What does exactly mean this sentence from this oracle java tutorial:

A relative path cannot be constructed if only one of the paths includes a root element. If both paths include a root element, the capability to construct a relative path is system dependent.

With "system dipendent" do they mean only that if an element contains a root it will work only in the platform specific syntax that has been written? I guess it is the only thing they mean. Are there any other ways of reading that?

for example :

public class AnotherOnePathTheDust {
    public static void main (String []args)
    {
    Path p1 = Paths.get("home");
    Path p3 = Paths.get("home/sally/bar"); //with "/home/sally/bar" i would get an exception.
    // Result is sally/bar
    Path p1_to_p3 = p1.relativize(p3);
    // Result is ../..

    Path p3_to_p1 = p3.relativize(p1);
    System.out.println(p3_to_p1);   }
}

The exception that I get by using "/home/sally/bar" instead of "home/sally/bar" (without root) is this one:

 java.lang.IllegalArgumentException: 'other' is different type of Path

Why does it not work? what is the conflict with the system that they mean?

like image 470
Rollerball Avatar asked Apr 30 '13 12:04

Rollerball


People also ask

What is the path class in java?

As its name implies, the Path class is a programmatic representation of a path in the file system. A Path object contains the file name and directory list used to construct the path, and is used to examine, locate, and manipulate files. A Path instance reflects the underlying platform.

How do you create an absolute path in java?

The getAbsolutePath() method is a part of File class. This function returns the absolute pathname of the given file object. If the pathname of the file object is absolute then it simply returns the path of the current file object. For Example: if we create a file object using the path as “program.


3 Answers

Because p1 and p3 has different root.

If you use use "/home/sally/bar" instead of "home/sally/bar" for p3, then p3.getRoot() will return / but p1.getRoot() is null.

You'll know why you got this exception after you read following codes (comes from http://cr.openjdk.java.net/~alanb/6863864/webrev.00/src/windows/classes/sun/nio/fs/WindowsPath.java-.html Line374-375):

// can only relativize paths of the same type
if (this.type != other.type)
     throw new IllegalArgumentException("'other' is different type of Path");
like image 157
kongyk Avatar answered Sep 22 '22 20:09

kongyk


I did some tests of your example. Actually the exception you are mentioning appears only when one of the paths contains root and the other not (exactly like the sentence says) E.g:

  • /home/sally/bar
  • home

It works ok if both paths contain roots. The "system dependent" means probably such case on Windows:

  • C:\home
  • D:\home\sally\bar

Above gives following exception:

java.lang.IllegalArgumentException: 'other' has different root

You will never face something like this (exception for both paths containing root - absolute paths) on Unix

like image 21
macias Avatar answered Sep 23 '22 20:09

macias


As other answers already mentioned this is due to the different roots in the path.

To work around that, you can use toAbsolutePath().

For example:

public class AnotherOnePathTheDust {
  public static void main (String []args)
  {
    Path p1 = Paths.get("home").toAbsolutePath();
    Path p3 = Paths.get("/home/sally/bar").toAbsolutePath();

    Path p1_to_p3 = p1.relativize(p3);

    Path p3_to_p1 = p3.relativize(p1);
    System.out.println(p3_to_p1);
  }
}
like image 35
stempler Avatar answered Sep 25 '22 20:09

stempler