new File("") vs. new File("."): Feature or Bug?
new File("")
and new File(".")
yield the same canonical path, yet the former object is unsubable. Consider below code, and how both objects return the same canonical path. The documentation states the canonical path is "both absolute and unique". Yet only the File created with the "." argument is actually usable.
Shouldn't an exception be thrown at some point? Either in the empty string constructor call (since the object created doesn't seem valid), or at least in getCanonicalPath (which at least declares IOException)?
import java.io.File;
import java.io.IOException;
public abstract class Test {
public static void main(String[] args) throws Exception {
testFile("");
testFile(".");
}
private static void testFile(String arg) throws IOException {
System.out.format("File constructor argument: \"%s\"\n", arg);
File g = new File(arg);
System.out.format("toString() = \"%s\"\n", g.toString());
System.out.format("getAbsolutePath() = \"%s\"\n", g.getAbsolutePath());
System.out.format("getAbsoluteFile() = \"%s\"\n", g.getAbsoluteFile());
System.out.开发者_如何学Goformat("getgetCanonicalPath() = \"%s\"\n", g.getCanonicalPath());
System.out.format("getgetCanonicalFile() = \"%s\"\n", g.getCanonicalFile());
System.out.format("exists() = %s\n", g.exists());
System.out.format("isDirectory() = %s\n", g.isDirectory());
System.out.println();
}
}
And the output that it produces:
File constructor argument: ""
toString() = ""
getAbsolutePath() = "C:\usr\workspace\Test"
getAbsoluteFile() = "C:\usr\workspace\Test"
getgetCanonicalPath() = "C:\usr\workspace\Test"
getgetCanonicalFile() = "C:\usr\workspace\Test"
exists() = false
isDirectory() = false
File constructor argument: "."
toString() = "."
getAbsolutePath() = "C:\usr\workspace\Test\."
getAbsoluteFile() = "C:\usr\workspace\Test\."
getgetCanonicalPath() = "C:\usr\workspace\Test"
getgetCanonicalFile() = "C:\usr\workspace\Test"
exists() = true
isDirectory() = true
While using the constructor with the empty String, you create a File instance that has two properties :
- It does not actually exists.
- Its absolute pathname is the "empty abstract pathname"
When using File("."), you create a different file :
- It DOES exist on the file system
- Its absolute pathname contains the "." character
This second file exists, not the first. The second file is consequently the only one that is supposed to respect the rule explained in getCanonicalPath :
Every pathname that denotes an existing file or directory has a unique canonical form.
As the first file is not real, the fact that their canonical paths are equal is meaningless.
Consequently, the behviour you've pointed is not a bug. It's the one we expected from the JVM.
You'll find all the infos in the javadoc
By passing an empty string to the constructor, you are creating an empty 'abstract pathname'. From the java.io.File Javadoc:
If the given string is the empty string, then the result is the empty abstract pathname.
The 'empty abstract pathname' in this case does not physically exist, hence exists()
evaluates to false
. The reason you get a directory for the empty string is described in the Javadoc of getAbsolutePath
:
If this abstract pathname is the empty abstract pathname then the pathname string of the current user directory, which is named by the system property user.dir, is returned.
According to the javaDocs :
Every pathname that denotes an existing file or directory has a unique canonical form.
In your first example, you are referring to "the file that has no name".
As that one does not exist, I don't think it's a bug that new File("") and new File(".") yield the same canonical path.
精彩评论