java 获取发布后的路径问题_Java 中获取资源(文件)的路径问题总结

本文总结了Java中获取资源文件路径的两种主要方式:基于文件系统和基于classpath。对于基于文件系统的路径,可以使用File构造函数,相对路径基于System.getProperties("user.dir")。对于基于classpath,介绍了使用Class.getResource()和ClassLoader.getResource()的细节,包括如何处理相对路径和从根目录开始查找。文章还讨论了在不同环境下,如Tomcat,如何选择合适的方法获取资源。
摘要由CSDN通过智能技术生成

Java 中获取资源(文件)的路径问题总结

?

首先,Java 中获取资源大体上可分为两种方式,基于 文件系统的 和 基于classpath的.

?

?

1. 基于文件系统的相对简单.

?

? ?比如 构造一个File f = new File('text.txt');

? ?这里传递给File构造函数的可以是相对路径比如text.txt就是相对路径,

? ?也可以是绝对路径比如 new File('C:/text.txt');

? ?

? ?需要注意的是,这里相对路径,相对的是System.getProperties("user.dir")的

? ?比如 你用window中的cmd 通过调用java命令来来执行一个java程序,

? ?那么,cmd中的当前路径,就是Java程序中的相对路径

? ?

? ?比如 C:\> ?java test 执行这条命令,相对路径就在C盘.

? ?

2. 基于classpath的

?

? ?我们知道,java 命令执行的时候可以指定一个classpath,系统默认在这个classpath目录

? ?下面查找各种calss.文件,jar包,配置文件等.

? ?

? ?基于classpath 获取资源有以下三种方式:

? ?

? ?

URL url = this.getClass().getResource("resource_name");

URL url = this.getClass().getClassLoader().getResource("resource_name");

URL url = Thread.currentThread().getContextClassLoader().getResource("resource_name");

?

?

? ?

? ?第一种是通过Class类实例的getResource方法,后面两种都是ClassLoader类实例的getResource方法.

? ?

? ?Class.getResource()也是委托ClassLoader的getResource方法来实现的.

? ?

? ?所以,先说ClassLoader的getResource方法:

? ?

? ?(1) ClassLoader的getResource方法参数不能以"/"开头,而且必须是从根目录开始查找,

? ?

? ?这里的根目录是classpath中的目录以及包含引用的jar.

? ?比如eclipse的默认将每个工程中Java类运行时的classpath设置为:?

? ?工程根目录/bin目录 以及 工程中引用的所有jar包.

? ?

? ?在编译的时候,将src目录结构拷贝到bin目录中,将java类编译成class文件后连同其他文件按src中原始目录结构

? ?拷贝到bin目录中.

? ?

? ?假设某个工厂的classpath如下(两个):

? ?/bin

? ?log4j-1.2.16.jar

? ?

? ?其中log4j-1.2.16.jar中有目录结构org\apache\log4j\ (与包org.apach.log4j) 对应

? ?

? ?那么 查找bin目录下的test.txt文件 ?使用下面方法

? ?ClassLoader.getResource("test.txt");

? ?注意这里ClassLoader.getResource方法的入参必须是从根目录开始查找,这里根目录就是classpath中的/bin.

? ?找 bin/level1/level2/ll.txt文件必须使用

? ?ClassLoader.getResource("level1/level2/ll.txt"); //注意查找必须基于根目录(/bin),并且目录结构也要写对,不能用/开头

? ?

? ?(2) Class.getResource() 略有不同:?

? ? ? ?(a)可以通过相对路径查找,相对的是 当前实例的Class文件所在的包;

? ? ? ?(b)也可以和ClassLoader.getResource()一样从根目录(classpath)开始查找,

? ? ? ? ? 但是此时传递给Class.getResource()的参数必须要用 "/" 开头,

? ? ? ? ? 否则就是相对查找了((a)中的情况)

? ? ? ? ? 其实,这种代码就是将/去掉,然后调用ClassLoader.getResource()

? ? ? ? ? 参考代码:

? ? ? ? ??

public java.net.URL getResource(String name) {

name = resolveName(name);

ClassLoader cl = getClassLoader0();

if (cl==null) {

// A system class.

return ClassLoader.getSystemResource(name);

}

return cl.getResource(name);

}

private String resolveName(String name) {

if (name == null) {

return name;

}

if (!name.startsWith("/")) {

Class c = this;

while (c.isArray()) {

c = c.getComponentType();

}

String baseName = c.getName();

int index = baseName.lastIndexOf('.');

if (index != -1) {

name = baseName.substring(0, index).replace('.', '/')

+"/"+name;

}

} else {

name = name.substring(1);

}

return name;

}

?

? ? ? ? ??

? ? 需要注意的是,这种基于classpath查找的情况,在写代码之前需要把各种系统的classpath研究清楚.

? ? 比如Tomcat的不同版本classpath的设置不同,需要了解清楚(参考:http://my.oschina.net/dongming/blog/64142)

? ??

? ? 关于 getClassLoader().getResource 和 Thread.currentThread().getContextClassLoader().getResource区别:

? ? 因为类似Tomcat这类的容器,可能使用了自定义的ClassLoader产生了特殊的classpath,这样就需要遵循特殊的方式,

? ? Thread.currentThread().getContextClassLoader()返回该线程的上下文 ClassLoader,再调用getResource更保险

? ? 一些,一般推荐使用Thread.currentThread().getContextClassLoader().getResource方式获取资源.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值