Java 相对路径

路径基准

系统参数user.dir一般是JVM启动时的用户文件夹
Eclipse中运行一个类的main函数,JVM在项目根目录启动,相对的路径基准是项目的根目录

假设在workspace下有个test项目,包名sample,类名Test.java

Sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Test {
public static void main(String[] args) throws IOException, URISyntaxException, ClassNotFoundException {
System.out.println(System.getProperty("user.dir")); //项目根目录 C:\workspace\test
System.out.println(Test.class.getResource("")); //Test类的加载目录 file:/C:/workspace/test/bin/sample/
System.out.println(Test.class.getResource("/")); //Test类的加载根目录 file:/C:/workspace/test/bin/

System.out.println(Thread.currentThread().getContextClassLoader().getResource("")); //类加载器的目录 file:/C:/workspace/test/bin/
System.out.println(Test.class.getClassLoader().getResource("")); //类加载器的目录 file:/C:/workspace/test/bin/
System.out.println(ClassLoader.getSystemResource("")); //类加载器的目录 file:/C:/workspace/test/bin/

System.out.println(Thread.currentThread().getContextClassLoader() == Test.class.getClassLoader()); //true 同一加载器

File file = new File("/foo.txt");
System.out.println(file.getAbsolutePath()); //绝对文件系统根目录 C:\foo.txt
file = new File("foo.txt");
System.out.println(file.getAbsolutePath()); //相对项目根目录 C:\workspace\test\foo.txt
file = new File(Paths.get("src", "").toUri());
System.out.println(file.getAbsolutePath()); //相对项目根目录 C:\workspace\test\src
}
}

基准

  • 类和加载器的路径基准是class文件所在的目录
  • 资源路径基准是user.dir设定的目录

基准选择

  • user.dir随运行环境变化,如果访问项目内文件sample/Test.java,在IDE内运行没问题,然而打包后放在别的路径就会出错,因为参照的位置变化了
  • ClassLoader获取路径比较稳妥Test.class.getResourceAsStream("/sample/Test.java")可以在正确的路径找到