关于资源路径的实验小结

   java中关于获取程序运行时资源路径的方法,在iteye中搜索到了几个。下面我对这几种写法做个实验。

说明:实验分直接编译运行和用fat jar打成包后运行两部分,因为我相信这个定位资源的问题正是在打包后和在linux服务器上运行时才会遇到的。Eclipse工程名testjar,位于E:\Java\Workspaces\,工程内只有一个类dut.ir.TestJar,资源文件1位于dut/ir/。fat jar选项不选One-Jar。

 

先来看Class.getResource()方法

public class TestJar
{
    public static void main(String[] args)
    {
        System.out.println(TestJar.class.getResource(资源名));
    }
}

  如果资源名填"/",Eclipse里运行时这个方法返回“file:/E:/Java/Workspaces/testjar/bin/”,而在打包后运行时返回null;

  如果资源名填"",Eclipse里运行返回“file:/E:/Java/Workspaces/testjar/bin/dut/ir/”,而在打包后运行则返回“jar:file:/E:/Java/Workspaces/testjar/testjar_fat.jar!/dut/ir/”,也就是类所在的完整路径(文件系统路径+包路径);

  如果资源名以'/'开头,如"/dut/ir/1",Eclipse运行结果“file:/E:/Java/Workspaces/testjar/bin/dut/ir/1”,打包运行结果则是“jar:file:/E:/Java/Workspaces/testjar/testjar_fat.jar!/dut/ir/1”,也就是说在包结构的根位置寻找,若资源名写“/1”或"/ir/1"是找不到的;

  如果资源名不以'/'开头,如"1",Eclipse运行结果“file:/E:/Java/Workspaces/testjar/bin/dut/ir/1”,打包运行结果则是“jar:file:/E:/Java/Workspaces/testjar/testjar_fat.jar!/dut/ir/1”,也就是说在类所在的位置上寻找,若资源名写"dut/ir/1"就意味着定位dut/ir/dut/ir/1,当然找不到;

 

    再实验TestJar.class.getClassLoader().getResource(资源名),ClassLoader.getSystemResource(资源名)和Thread.currentThread().getContextClassLoader().getResource(资源名)方法,它们的结果和TestJar.class.getResource("/" + 资源名)相同。关于原因,这在jdk中Class.getResource方法的说明

写道
此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)。

 

    那么,如果想在jar包所在的位置定位资源怎么办?再看看这几个方法:

System.out.println(System.getProperty("user.dir"));
System.out.println(System.getProperty("java.class.path"));
System.out.println(new File("").getAbsolutePath());
System.out.println(TestJar.class.getProtectionDomain().getCodeSource().getLocation().getFile());

 输出

E:\Java\Workspaces\testjar
E:\Java\Workspaces\testjar\bin
E:\Java\Workspaces\testjar
/E:/Java/Workspaces/testjar/bin/

 如此,可以利用System.getProperty("user.dir")或new File("").getAbsolutePath()这两种写法。

 

    注意:我这里都是直接引用类来实验这些方法,而没有实例化。进来看过的学长如有指正敬请回复,多谢!

你可能感兴趣的:(路径)