为什么 Path.relativize 在 Java 8 和 Java 11 上表现不同?
Why does Path.relativize behave differently on Java 8 and Java 11?
为什么方法 relativize
在 java-8 and java-11 上表现不同?
Path path1 = Paths.get("/a/./b/../image.png");
Path path2 = Paths.get("/a/file.txt");
Path path = path1.relativize(path2);
System.out.println(path);
- java-8 (1.8.0_66 to be exact) prints
../../../../file.txt
. JavaDoc.
- java-11 (11.0.4 to be exact) prints
../file.txt
. JavaDoc.
两个版本的 JavaDoc 描述相同。我觉得 java-11 方式对我来说是正确的行为:
path1
:/a/./b/../image.png
标准化为 /a/b/../image.png
,后者标准化为 /a/image.png
path2
: /a/file.txt
- 从
/a/image.png
和 /a/file.txt
到 导航 的方法是 ../file.txt
问题
java-8的方式应该如何计算?它不会规范化路径吗?我不明白如何从 head.
中得到结果
为什么这两个版本之间存在根本没有记录的差异?
也许这个错误会回答你的问题:
https://bugs.openjdk.java.net/browse/JDK-8066943
这影响了包含 .或 .. 并已为 Java 9 修复。
这就是为什么您会看到 8 和 11 之间存在差异的原因。
Windows 基于 source-code 在这里回答。
观察java-11 is has additional code including normalization compared to java-8.
中的源码(先看sun.nio.fs.WindowsPath
,Path
的实现之一)
- java-8
sun.nio.fs.WindowsPath
源代码位于 GitHub
- java-11
sun.nio.fs.WindowsPath
源代码位于 GitHub
后一个实现的关键行从411行开始,所以基本上,后一个实现规范化路径之前考虑计算相对路径:
WindowsPath base = this;
if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
base = base.normalize();
child = child.normalize();
}
进一步挖掘,实现在 jdk8-b120
(source) and jdk-9+95
(来源)之间发生变化。由于引入了模块化系统,两者 类 实现和位置不同:
- Java 8 岁及以下:
/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
- Java 9 岁及以上:
/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java
How is the java-8 way supposed to be calculated? Doesn't it normalize the path? I don't understand how to get the result from head.
最直接的方法是先规范化两条路径,然后再相对化它们。但我不知道它是否完全涵盖所有 java.nio.file.Path
实现并且这样做是否安全。
Path path = path1.normalize().relativize(path2.normalize());
为什么方法 relativize
在 java-8 and java-11 上表现不同?
Path path1 = Paths.get("/a/./b/../image.png");
Path path2 = Paths.get("/a/file.txt");
Path path = path1.relativize(path2);
System.out.println(path);
- java-8 (1.8.0_66 to be exact) prints
../../../../file.txt
. JavaDoc. - java-11 (11.0.4 to be exact) prints
../file.txt
. JavaDoc.
两个版本的 JavaDoc 描述相同。我觉得 java-11 方式对我来说是正确的行为:
path1
:/a/./b/../image.png
标准化为/a/b/../image.png
,后者标准化为/a/image.png
path2
:/a/file.txt
- 从
/a/image.png
和/a/file.txt
到 导航 的方法是../file.txt
问题
java-8的方式应该如何计算?它不会规范化路径吗?我不明白如何从 head.
中得到结果为什么这两个版本之间存在根本没有记录的差异?
也许这个错误会回答你的问题: https://bugs.openjdk.java.net/browse/JDK-8066943
这影响了包含 .或 .. 并已为 Java 9 修复。 这就是为什么您会看到 8 和 11 之间存在差异的原因。
Windows 基于 source-code 在这里回答。
观察java-11 is has additional code including normalization compared to java-8.
中的源码(先看sun.nio.fs.WindowsPath
,Path
的实现之一)
- java-8
sun.nio.fs.WindowsPath
源代码位于 GitHub - java-11
sun.nio.fs.WindowsPath
源代码位于 GitHub
后一个实现的关键行从411行开始,所以基本上,后一个实现规范化路径之前考虑计算相对路径:
WindowsPath base = this;
if (base.hasDotOrDotDot() || child.hasDotOrDotDot()) {
base = base.normalize();
child = child.normalize();
}
进一步挖掘,实现在 jdk8-b120
(source) and jdk-9+95
(来源)之间发生变化。由于引入了模块化系统,两者 类 实现和位置不同:
- Java 8 岁及以下:
/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java
- Java 9 岁及以上:
/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java
How is the java-8 way supposed to be calculated? Doesn't it normalize the path? I don't understand how to get the result from head.
最直接的方法是先规范化两条路径,然后再相对化它们。但我不知道它是否完全涵盖所有 java.nio.file.Path
实现并且这样做是否安全。
Path path = path1.normalize().relativize(path2.normalize());