在 Java 9 中,WinNTFileSystem 类(Windows 的文件系统实现)发生了变化。
它可能解决了类认为绝对路径是什么的方式的问题。我没有找到确切指定这个的错误,但有些接近。
File.isAbsolute() 状态:
在 Microsoft Windows 系统上,如果路径名的前缀是
驱动器说明符后跟“\”,或者如果它的前缀是“\\”。
所以根据规范,对于以下内容:
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // not absolute according to the spec
File xx = new File("C:\\", "Workspace");
System.out.println(xx.isAbsolute());
File xxx = new File("\\\\Workspace");
System.out.println(xxx.isAbsolute());
我们期望:
假的
真的
真的
但我们得到:
真
真的
真的
从 Java 9 开始,它会产生预期的结果。
问题是在 Java 9 之前没有\ 的路径都被视为绝对路径:
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // true
虽然情况不应该如此。
具体来说,主要变化涉及WinNTFileSystem 类的resolve(String parent, String child) 方法。
之前,resolve() 通过在父子路径之间添加斜杠来解析抽象路径,以用于任何不以斜杠开头的子路径。
从 Java 9 开始,如果父项是驱动器,resolve() 将不再在父项和子项之间添加斜杠。
这里是change:
boolean isDirectoryRelative =
pn == 2 && isLetter(parent.charAt(0)) && parent.charAt(1) == ':';
if (child.charAt(childStart) == slash || isDirectoryRelative) {
theChars = new char[strlen]; ^-------- this one was added from Java 9
parent.getChars(0, parentEnd, theChars, 0);
child.getChars(childStart, cn, theChars, parentEnd);
} else {
theChars = new char[strlen + 1];
parent.getChars(0, parentEnd, theChars, 0);
theChars[parentEnd] = slash;
child.getChars(childStart, cn, theChars, parentEnd + 1);
}
后果
关于你的问题:
请问您是否有任何已知问题或解决方案
案例
两个 JDK 版本之间的差异很重要。
它涉及抽象路径名的规范化路径名 (File.getPath()) 的值和绝对路径 File.getAbsolutePath() 的值,因为现在 new File("C:", "Workspace") 生成相对路径。
如果您的应用程序依赖 File.getPath() 对其进行一些解析,则它可能会有不同的行为并产生一些问题。
要在 JDK 版本之间拥有可移植的代码,解析路径上的任何解析都应视为可选的 \,紧跟在 Windows 驱动器之后。
这样C:\ 和C: 将以相同的方式处理。
如果您的应用程序依赖于File.getAbsolutePath(),Java 9 也可能会带来一些惊喜,因为现在相对路径将针对文件系统进行解析(之前作为绝对路径,它只是返回自身)。
所以相反,你应该使用File.getPath() 来不解析文件系统的路径。