I am trying to familiarize myself with java.nio.file.Path.relativize() to no avail.
I have read the javadocs, and I have seen examples. However, I still cannot get my
First of all, the current working directory is completely irrelevant. I could reproduce your problem even under Windows, not having any of these files and directories on my system, the only difference being the use of \\
instead of /
.
What should relativize
do? If you have a path like foo bar baz
and ask for relativizing foo bar hello
, you’ll get .. hello
as that’s the path, relative to foo bar baz
to get to foo bar hello
, i.e Paths.get("foo", "bar", "baz").resolve(Paths.get("..", "hello")).normalize()
produces the same path as Paths.get("foo", "bar", "hello")
, regardless of any real file system structure.
Now you ran into the bug JDK-6925169, as suggested by the user Berger in a comment. The Path
implementation does not handle .
and ..
components correctly in relativize
, but treats them like any other path component.
So whether you use Paths.get("..", "..", "temp", "delete", "dictionary.txt")
or Paths.get("a", "b", "c", "d", "e")
, it makes no difference, in either case, the implementation treats it as five nonmatching path components that have to be removed to resolve to Paths.get("zoo.txt")
. This applies to both, Windows and Linux. You may verify it with the following platform-independent code:
Path relative = Paths.get("zoo.txt");
Path base1 = Paths.get("..", "..", "temp", "delete", "dictionary.txt");
Path base2 = Paths.get("a", "b", "c", "d", "e");
Path relativized1 = base1.relativize(relative);
System.out.println("relativized1: "+relativized1);
Path relativized2 = base2.relativize(relative);
System.out.println("relativized2: "+relativized2);
Path resolved1 = base1.resolve(relativized1).normalize();
System.out.println("resolved1="+resolved1);
Path resolved2 = base2.resolve(relativized2).normalize();
System.out.println("resolved2="+resolved2);
Since relatize
incorrectly treats all component the same, the relativized paths are the same, but since the normalize
operation does handle the ..
path components, the first resolved path will exhibit the problem whereas the second resolves to the expected zoo.txt
.
It might be important for the understanding, that all path components, including dictionary.txt
, are treated like directories. The documentation of relativize
doesn’t mention that explicitly, but you can derive it from the documented relationship to resolve, whose documentation says “… this method considers this path to be a directory”.