It's looks like java.io.File.(File, String) is JDK version dependent. Code example was run on Windows 10.
Code example:
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
}
Could you please address is there any known issue or solution for the case
Java.io.File Class in Java. The File class is Java’s representation of a file or directory path name. Because file and directory names have different formats on different platforms, a simple string is not adequate to name them.
The File class is Java’s representation of a file or directory path name. Because file and directory names have different formats on different platforms, a simple string is not adequate to name them.
The java.nio.file package defines interfaces and classes for the Java virtual machine to access files, file attributes, and file systems. This API may be used to overcome many of the limitations of the java.io.File class.
A File object is created by passing in a String that represents the name of a file, or a String or another File object. For example, Attention reader! Don’t stop learning now.
In Java 9, the WinNTFileSystem
class (FileSystem implementation for windows) changed.
It probably solves a issue which the way the class considers what a absolute path is. I didn't find a bug that exactly specifies this one but some are close to.
File.isAbsolute()
states :
On Microsoft Windows systems, a pathname is absolute if its prefix is a drive specifier followed by "\", or if its prefix is "\\".
So according to the specification, for the following:
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());
we expect :
false true true
But we get :
true true true
From Java 9 it produces the expected result.
The problem is that before Java 9 a path without \
is all the same considered as an absolute path :
File x = new File("C:", "Workspace");
System.out.println(x.isAbsolute()); // true
While that this should not be the case.
Concretely, the main changes concern the resolve(String parent, String child)
method of the WinNTFileSystem
class.
Before, resolve()
resolved the abstract path by adding a slash between the parent and the child for any child path that doesn't start with a slash.
From Java 9, resolve()
doesn't add a slash any longer between the parent and the child if the parent is a drive.
Here is the 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);
}
Consequences
About your question :
Could you please address is there any known issue or solution for the case
The difference between the two JDK versions matters.
It concerns both the value of the abstract pathname's normalized pathname (File.getPath()
) and the value of the absolute path File.getAbsolutePath()
as now new File("C:", "Workspace")
produces a relative path.
If your application relies on File.getPath()
to do some parsing on that, it could have a distinct behavior and create some issues.
To have a portable code between the JDK versions, any parsing on the resolved path should consider as optional the \
just after the Windows drive.
In this way C:\
and C:
would be handled in the same way.
If your application relies on File.getAbsolutePath()
, it could also have some surprises from Java 9 as now the path that is relative will be resolved against the filesystem (before as an absolute path this just returned itself).
So instead, you should so probably use File.getPath()
to not resolve the path against the file system.
Addition to @david answer,
It was a bug#8153250, which was address and fixed version is available JDK 9 b153
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With