java.io.File.<init>(File,String) JDK 版本依赖
java.io.File.<init>(File,String) JDK version dependent
看起来 java.io.File.(File, String) 是 JDK 版本相关的。
代码示例是 运行 on Windows 10.
代码示例:
public static void main(String... args) {
String path = "C:\Workspace\project";
File file = null;
for (String part : path.split("\\")) {
file = new File(file, part);
}
System.out.println(file);
// prints "C:Workspace\project" for JDK 9+
// prints "C:\Workspace\project" for JDK 8
}
您能否解决此案例是否存在任何已知问题或解决方案
在 Java 9 中,WinNTFileSystem
class(windows 的文件系统实现)已更改。
它可能解决了 class 考虑绝对路径的方式的问题。我没有找到准确指定此错误的错误,但有些接近。
File.isAbsolute()
状态:
On Microsoft Windows systems, a pathname is absolute if its prefix is
a drive specifier followed by "\", or if its prefix is "\".
所以根据规范,对于以下内容:
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());
我们预计:
false
true
true
但是我们得到:
true
true
true
从 Java 9 它产生了预期的结果。
问题是在 Java 9 之前,没有 \
的路径都被视为绝对路径:
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // true
虽然事实并非如此。
具体来说,主要变化涉及 WinNTFileSystem
class 的 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);
}
后果
关于您的问题:
Could you please address is there any known issue or solution for the
case
两个 JDK 版本之间的区别很重要。
它涉及抽象路径名的规范化路径名 (File.getPath()
) 的值和绝对路径 File.getAbsolutePath()
的值,因为现在 new File("C:", "Workspace")
生成相对路径。
如果您的应用程序依赖 File.getPath()
对其进行一些解析,它可能会有不同的行为并产生一些问题。
要在 JDK 版本之间具有可移植代码,解析路径上的任何解析都应将 Windows 驱动器之后的 \
视为可选。
这样 C:\
和 C:
将以相同的方式处理。
如果您的应用程序依赖于 File.getAbsolutePath()
,它也可能会从 Java9 中得到一些惊喜,因为现在相对路径将针对文件系统进行解析(之前作为绝对路径,这只是自行返回)。
因此,您应该使用 File.getPath()
来不解析针对文件系统的路径。
@david 回答的补充,
这是一个bug#8153250,这是地址和固定版本可用JDK 9 b153
。
正如@davidxxx 指出的那样,getAbsoluteFile
或 getAbsolutePath
在初始文件实例上与 Java8 和 Java9 相同。但是,如果您决定使用这个初始文件创建一个新文件,您可能会对其中的差异感到惊讶 - 至少我是。
public static void main(String[] args) throws Exception {
File file = new File((File)null, "C:");
System.out.println(file);
System.out.println(file.getAbsoluteFile());
System.out.println("----");
file = new File(file, "Windows");
System.out.println(file);
System.out.println(file.getAbsoluteFile());
}
如果你用 Java 执行上面的程序,8 和 9 file
将在第二次分配后指向完全不同的文件夹。由于 Java8 和 9 的初始文件相同,我实际上认为这是 Java 8(可能之前)中的错误。
输出Java8:
C:
C:\ws\PLAYGROUND\test
----
C:\Windows
C:\Windows
输出Java9:
C:
C:\ws\PLAYGROUND\test
----
C:Windows
C:\ws\PLAYGROUND\test\Windows
看起来 java.io.File.(File, String) 是 JDK 版本相关的。 代码示例是 运行 on Windows 10.
代码示例:
public static void main(String... args) {
String path = "C:\Workspace\project";
File file = null;
for (String part : path.split("\\")) {
file = new File(file, part);
}
System.out.println(file);
// prints "C:Workspace\project" for JDK 9+
// prints "C:\Workspace\project" for JDK 8
}
您能否解决此案例是否存在任何已知问题或解决方案
在 Java 9 中,WinNTFileSystem
class(windows 的文件系统实现)已更改。
它可能解决了 class 考虑绝对路径的方式的问题。我没有找到准确指定此错误的错误,但有些接近。
File.isAbsolute()
状态:
On Microsoft Windows systems, a pathname is absolute if its prefix is a drive specifier followed by "\", or if its prefix is "\".
所以根据规范,对于以下内容:
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());
我们预计:
false true true
但是我们得到:
true true true
从 Java 9 它产生了预期的结果。
问题是在 Java 9 之前,没有 \
的路径都被视为绝对路径:
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // true
虽然事实并非如此。
具体来说,主要变化涉及 WinNTFileSystem
class 的 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);
}
后果
关于您的问题:
Could you please address is there any known issue or solution for the case
两个 JDK 版本之间的区别很重要。
它涉及抽象路径名的规范化路径名 (File.getPath()
) 的值和绝对路径 File.getAbsolutePath()
的值,因为现在 new File("C:", "Workspace")
生成相对路径。
如果您的应用程序依赖 File.getPath()
对其进行一些解析,它可能会有不同的行为并产生一些问题。
要在 JDK 版本之间具有可移植代码,解析路径上的任何解析都应将 Windows 驱动器之后的 \
视为可选。
这样 C:\
和 C:
将以相同的方式处理。
如果您的应用程序依赖于 File.getAbsolutePath()
,它也可能会从 Java9 中得到一些惊喜,因为现在相对路径将针对文件系统进行解析(之前作为绝对路径,这只是自行返回)。
因此,您应该使用 File.getPath()
来不解析针对文件系统的路径。
@david 回答的补充,
这是一个bug#8153250,这是地址和固定版本可用JDK 9 b153
。
正如@davidxxx 指出的那样,getAbsoluteFile
或 getAbsolutePath
在初始文件实例上与 Java8 和 Java9 相同。但是,如果您决定使用这个初始文件创建一个新文件,您可能会对其中的差异感到惊讶 - 至少我是。
public static void main(String[] args) throws Exception {
File file = new File((File)null, "C:");
System.out.println(file);
System.out.println(file.getAbsoluteFile());
System.out.println("----");
file = new File(file, "Windows");
System.out.println(file);
System.out.println(file.getAbsoluteFile());
}
如果你用 Java 执行上面的程序,8 和 9 file
将在第二次分配后指向完全不同的文件夹。由于 Java8 和 9 的初始文件相同,我实际上认为这是 Java 8(可能之前)中的错误。
输出Java8:
C:
C:\ws\PLAYGROUND\test
----
C:\Windows
C:\Windows
输出Java9:
C:
C:\ws\PLAYGROUND\test
----
C:Windows
C:\ws\PLAYGROUND\test\Windows