Noticed this today.
Given that a file named \"existing\" exists in the PWD of a java process (windows).
new File(\"existing\").exists() => true
Remember that "" is NOT the same as null. Thusly
new File("", "existing").exists()
does not assume the . directory. As @Dylan Halperin said, on Linux using "" directs to the root / directory, as I found using this code:
import java.io.*;
class FileTest {
public static void main(String args[]) {
String nullStr = null;
File f1 = new File(nullStr, "f1");
File f2 = new File("", "tmp");
System.out.println("f1.exists(): " + f1.exists());
System.out.println("f2.exists(): " + f2.exists());
}
}
Output:
f1.exists(): true
f2.exists(): true
Yes, I had created a file named "f1" in the working directory.
I remember encountering this many moons ago, so I did some digging in the actual source. Here is the relevant source documentation from File.java:
/* Note: The two-argument File constructors do not interpret an empty
parent abstract pathname as the current user directory. An empty parent
instead causes the child to be resolved against the system-dependent
directory defined by the FileSystem.getDefaultParent method. On Unix
this default is "/", while on Microsoft Windows it is "\\". This is required for
compatibility with the original behavior of this class. */
So, the non-obvious behavior appears to be due to legacy reasons.
The two argument constructor expects a parent directory name, so your second line looks for a file whose relative path is "/existing". On a linux type system, "/" is the root (as far as I know), so /existing is very unlikely to exist. On windows, I'm not sure what it interprets that as by default, but if I open up a command line and say cd /Desktop
(working directory being my user folder) it says it can't find the path specified.
From java.io.File:
If parent is the empty string then the new File instance is created
by converting child into an abstract pathname and resolving the result
against a system-dependent default directory.
There's no mention of what the default directory is.
This is what's happening. But I agree because this is confusing
new File("", "test").getAbsolutePath() => /test
new File(".", "test").getAbsolutePath() => ${pwd}/test
I have no idea why this is the case because I had assumed it would also be pwd for the first one.