I'm using intellij for java developing, under my project/src directory, I got a "my.json" file, and my java program is:
import java.io.File;
public class My {
public static void main(String [] args){
String s = My.class.getResource(".") + "../../src/my.json";
File f = new File(s);
System.out.println(s+" exists: "+f.exists());
}
}
It prints:
file:/Users/x/java_local/target/classes/../../src/my.json exists: false
But if I "ls" under command line:
ls /Users/x/java_local/target/classes/../../src/my.json
Then I can see it.
So it seems that the java code constructed relative path is not valid. If I use absolute path in code, then it works.
I'm on mac. Any explanations on how this problem happens and how can I fix it?
The comparison you present in the question explains the nature of the problem clearly. Consider this code:
File f = new File(s); System.out.println(s+" exists: "+f.exists());
and the corresponding output:
file:/Users/x/java_local/target/classes/../../src/my.json exists: false
Evidently s
, the string you are attempting to use as a file name, is file:/Users/x/java_local/target/classes/../../src/my.json
. See that "file:" at the beginning? You have a valid String representation of a URL, but File(String)
expects the argument to be a plain path.
Possibly you want
File f = new File(new URI(s));
, but note that this will fail if your class is packaged inside a Jar, because then your URI will have the jar:
scheme, and File(URI)
accepts only URIs having the file:
scheme.
If you want to read a resource associated with your class and located relative to it, then I would suggest using Class.getResourceAsStream(relativePath)
and consuming the resulting InputStream
.