Java加载资源文件时的路径问题的解决办法

 更新时间:2013年04月26日 15:32:35   作者:  
今天偶然看到一篇关于tomcat加载servlet的文章,不由得想起了java加载资源文件的路径问题,资源文件可以使xml,properties,图片等,可以是任何文件

Java技术迷

加载资源文件比较常用的有两种:

一、用ClassLoader,说到这里就不得不提一下ClassLoader的分类,java内置的ClassLoader主要有三种,

第一种是根类加载器(bootstrap class loader),用C++来编写,负责将一些关键的Java类,如java.lang.Object和其他一些运行时代码先加载进内存中。 所负责加载的包:BootStrp------>JRE/lib/rt.jar

第二种是扩展类加载器(ExtClassLoader),由java类编写,负责将JRE中的一些类加载进内存中。所负责加载的包: ExtClassLoader---------->JRE/lib/ext/*.jar

第三种是应用类加载器(AppClassLoader)或者叫做系统类加载器,负责将CLASSPATH中的类加载到内存中。可以通过ClassLoader.getSystemClassLoader()来获取应用类加载器;


再来所说加类载器的继承,类加载器不是垂直继承的父子关系,而是一种组合关系,可以通过实例化类加载器时,将父类加载器的实例作为构造参数传到类加载器中。

关于类加载器的详细资料,可以自行搜索。
 

获取到应用类加载器之后,就是获取资源文件了,调用loader.getResource(path)可以加载相应路径下的资源文件,不能以‘/'开头,关于包内的资源可以把包当做普通的文件夹,以'/'分隔每个包。

如:URL url2 =  ClassLoader.getSystemClassLoader().getResource("demo/names.ser");是获取demo包内的names.ser序列化文件。

二、用需要加载的当前类的getResource方法来加载,其实这个方法也是调用的加载这个类的类加载器来获得资源文件的,只不过是获取的参数不同。

 (1)要想获取class所在包内的文件可以用相对路径直接访问包内的资源;如:Demo1.class.getResource("names.ser");获取的是Demo1的class文件所在包内的资源

 (2)要想获取包外的资源文件必须以‘/'开头,如URL url = Demo1.class.getResource("/demo/names.ser");获取的是demo包内的names.ser文件


其实第二种方式是对第一种方式的一个封装,都是用的ClassLoader来加载的资源文件。为什么这么说呢?看一下Class类的源码就知道:

复制代码 代码如下:

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

getResource根据传进来的name值(即相对路径或者绝对路径的形式),我们看到经过resolveName处理之后就调用了ClassLoader c1进行了加载,ClassLoader的加载路径的形式是不以‘/'开头的相对路径,那肯定是resolveName把路径转换了一把,再看看resolveName方法,首先判断是不是以‘/'开头,如果以‘/'开头,则为相对路径,否则就是绝对路径,注意else这个代码块,它将第一个字符去除掉了,确实去除掉之后就符合了ClassLoader的加载路径,而if块中就根据把当前类的包路径截取,然后将.替换成了'/',并添加上那段相对路径,也形成了符合ClassLoader的加载路径。

蓄力AI

微信公众号搜索 “ 脚本之家 ” ,选择关注

程序猿的那些事、送书等活动等着你

相关文章

  • Java8如何使用Lambda表达式简化代码详解

    Java8如何使用Lambda表达式简化代码详解

    这篇文章主要给大家介绍了关于Java8如何使用Lambda表达式简化的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • springcloud引入spring-cloud-starter-openfeign失败的解决

    springcloud引入spring-cloud-starter-openfeign失败的解决

    这篇文章主要介绍了springcloud 引入spring-cloud-starter-openfeign失败的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Springboot入门案例及部署项目的详细过程

    Springboot入门案例及部署项目的详细过程

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,本文给大家分享一个入门案例使用Springboot1.5.9搭建,具体配置部署过程跟随小编一起看看吧
    2021-07-07
  • mybatis框架之mybatis中dao层开发的两种方法

    mybatis框架之mybatis中dao层开发的两种方法

    这篇文章主要介绍了mybatis框架之mybatis中dao层开发的两种方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 数据库基本操作语法归纳总结

    数据库基本操作语法归纳总结

    本篇文章主要介绍了数据库的一些常用方法及一些基本操作,需要的朋友可以参考下
    2017-04-04
  • 关于ThreadLocal对request和response的用法说明

    关于ThreadLocal对request和response的用法说明

    这篇文章主要介绍了关于ThreadLocal对request和response的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Springboot与Maven多环境配置的解决方案

    Springboot与Maven多环境配置的解决方案

    多环境配置的解决方案有很多,我看到不少项目的多环境配置都是使用Maven来实现的,本文就实现Springboot与Maven多环境配置,感兴趣的可以了解下
    2021-06-06
  • 深入了解MyBatis分页机制

    深入了解MyBatis分页机制

    在企业项目的数据库操作中,分页查询是一个常见需求,尤其当数据量庞大时,MyBatis作为我们Java开发者的持久层框架,为分页提供了灵活的支持,本篇文章我们将深入探讨MyBatis的分页机制,使我们在实际开发项目中运用自如,需要的朋友可以参考下
    2023-12-12
  • 详解Spring 注解之@Import 注入的各种花活

    详解Spring 注解之@Import 注入的各种花活

    这篇文章主要介绍了详解Spring 注解之@Import 注入的各种花活,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Java实现24点小游戏

    Java实现24点小游戏

    这篇文章主要为大家详细介绍了Java实现24点小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01

最新评论