java resouce_Java Resource路径小结

首先一点很重要,Java中不存在标准的相对路径,各种相对路径取资源的方式都是基于某种规则转化为绝对路劲

然后一点也很重要,绝对不要直接使用绝对路径,否则死得很难看

基于以上两点,总结Resource路径问题无非归结为一点:找基点,也就是在某种环境下(web、j2ee或jar包等)通过合适的方式找到一个稳定的基点,然后通过这个基点找到你要的resource

Java中的基点有哪些呢?大致总结一下有以下几种:

1)classpath

如果你要找的资源在classpath下,那么通过classpath这个基点是比较合适的,而取得这个基点方式主要是通过ClassLoader来,具体方法就是ClassLoader.getResource(String name),或者ClassLoader.getSystemResourceAsStream("config/log4j.properties")。而取得ClassLoader的方式很多,比如:

Thread.currentThread().getContextClassLoader()

clazz.getClassLoader()

ClassLoader. getSystemClassLoader()

ClassLoader找resource的实现原理就是先递归在parent classLoader中从所在classpath里加载resource(最终如何加载JDK未开源),如果所有层级的classLoader都未找到,则调用findResource方法来找,而这个方法是暴露给自制classLoader来现实的,因此给了在classpath之外加载resource的机会。

如果还找不到文件就用spring里面的ResourcePatternResolver的实现类PathMatchingResourcePatternResolver,它可以支持文件和classpath的查找方式。用法如下:

@Testpublic void PathMatchingResourcePatternResolver1() throwsException{

ResourcePatternResolver loader= newPathMatchingResourcePatternResolver();

Resource[] resources= loader.getResources("classpath:/META-INF/ *.txt");for(int i=0;i< resources.length;i++) {

System.out.println(resources[i].getURL().getFile());

}

}

或者:

PathMatchingResourcePatternResolver resolover = new PathMatchingResourcePatternResolver();try{

Resource[] resources= null;

resources= resolover.getResources("file:E:/information/personal/workspace/poc/synchrophy/framework/src/test/synchrophy/com/sunvalley/framework/test/configuration/init*.properties");

System.out.println(resources.length);

}

2) 当前用户目录

就是相对于System.getProperty("user.dir" )返回的路径,对于一般项目,这是项目的根路径。对于JavaEE服务器,这可能是服务器的某个路径。这个并没有统一的规范! 然而,默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名,如new File("xxx"),就是在 System.getProperty("user.dir")路径下找xxx文件。因此,通过这种方式来定位文件可能会出现移植问题。

3)Web应用程序的根目录

在Web应用程序中,我们一般通过ServletContext.getRealPath("/")方法得到Web应用程序的根目录的绝对路径。

掌握了上面几个基点,就能很轻松得定位你要找的resource,只不过要清晰地认识到不要只图一时快活,而不管将来移植的死活,要确保能任何环境下(j2se or web,windows or linux)不出问题。

4)

1、Class的getResourceAsStream(String name)方法,参数不以"/"开头则默认从此类对应的.class文件所在的packge下取资源,以"/"开头则从CLASSPATH下获取

2、ClassLoader的getResourceAsStream(String name)方法,默认就是从CLASSPATH下获取资源,参数不可以以"/"开头

其实,Class的getResourceAsStream(String name)方法,只是将传入的name进行解析一下而已,最终调用的还是ClassLoader的getResourceAsStream(String name),看一下Class的getResourceAsStrea(String name)的源代码:

publicInputStream getResourceAsStream(String name) {

name=resolveName(name);

ClassLoader cl=getClassLoader0();if (cl==null) {//A system class.

returnClassLoader.getSystemResourceAsStream(name);

}returncl.getResourceAsStream(name);

}privateString resolveName(String name) {if (name == null) {returnname;

}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);

}returnname;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值