Java加载资源文件时的路径问题的解决办法
加载资源文件比较常用的有两种:
一、用ClassLoader,说到这里就不得不提一下ClassLoader的分类,java内置的ClassLoader主要有三种,
第一种是根类加载器(bootstrapclassloader),用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)可以加载相应路径下的资源文件,不能以‘/"开头,关于包内的资源可以把包当做普通的文件夹,以"/"分隔每个包。
如:URLurl2= ClassLoader.getSystemClassLoader().getResource("demo/names.ser");是获取demo包内的names.ser序列化文件。
二、用需要加载的当前类的getResource方法来加载,其实这个方法也是调用的加载这个类的类加载器来获得资源文件的,只不过是获取的参数不同。
(1)要想获取class所在包内的文件可以用相对路径直接访问包内的资源;如:Demo1.class.getResource("names.ser");获取的是Demo1的class文件所在包内的资源
(2)要想获取包外的资源文件必须以‘/"开头,如URLurl=Demo1.class.getResource("/demo/names.ser");获取的是demo包内的names.ser文件
其实第二种方式是对第一种方式的一个封装,都是用的ClassLoader来加载的资源文件。为什么这么说呢?看一下Class类的源码就知道:
publicjava.net.URLgetResource(Stringname){
name=resolveName(name);
ClassLoadercl=getClassLoader0();
if(cl==null){
//Asystemclass.
returnClassLoader.getSystemResource(name);
}
returncl.getResource(name);
}
privateStringresolveName(Stringname){
if(name==null){
returnname;
}
if(!name.startsWith("/")){
Classc=this;
while(c.isArray()){
c=c.getComponentType();
}
StringbaseName=c.getName();
intindex=baseName.lastIndexOf(".");
if(index!=-1){
name=baseName.substring(0,index).replace(".","/")
+"/"+name;
}
}else{
name=name.substring(1);
}
returnname;
}
getResource根据传进来的name值(即相对路径或者绝对路径的形式),我们看到经过resolveName处理之后就调用了ClassLoaderc1进行了加载,ClassLoader的加载路径的形式是不以‘/"开头的相对路径,那肯定是resolveName把路径转换了一把,再看看resolveName方法,首先判断是不是以‘/"开头,如果以‘/"开头,则为相对路径,否则就是绝对路径,注意else这个代码块,它将第一个字符去除掉了,确实去除掉之后就符合了ClassLoader的加载路径,而if块中就根据把当前类的包路径截取,然后将.替换成了"/",并添加上那段相对路径,也形成了符合ClassLoader的加载路径。
相关文章
- java局域网发送文件_Java如何实现局域网文件传输代码案例分享
- java用什么编译器_Java用Java编译「建议收藏」
- 面试官系统精讲Java源码及大厂真题 - 06 LinkedList 源码解析
- java 取余和取整_Java取整、取余
- 中级java笔试题_Java中级面试题合集[通俗易懂]
- Java 删除文件 被占用 已解决
- java源程序文件扩展名_JAVA源代码的扩展名为( )
- MySQL字段类型如何转为java_Java JDBC中,MySQL字段类型到JAVA类型的转换
- java反射 getMethod_JAVA 反射 getMethod() 和 invoke() 具体应用[通俗易懂]
- Java获取/resources目录下的资源文件方法
- Java反序列化工具-marshalsec
- Java中一些不为人知的写法
- 聊聊如何运用JAVA注解处理器(APT)
- java使用itext为pdf文件设置密码保护详解编程语言
- Java学习笔记之四java进制转化详解编程语言
- Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法详解编程语言
- java程序员必备技能SpringMvc入门介绍详解编程语言
- [Java]读取文件方法大全详解编程语言
- Java与Oracle联手构建数据库新世界(java和oracle)
- 服务器上的文件Java获取Linux服务器文件:简单又高效的操作方法(java获取linux)
- 策略解析Java项目中 Redis 过期策略(redisjava过期)
- Java文件在Linux系统中的使用(java文件linux)
- 运行Linux中定时运行Java程序的实用方法(linux定时java)
- Java如何在Linux下运行?(java执行linux)
- 合Java与Oracle联手打造崭新未来(java和oracle联)
- 数据库以Java运行环境构建基于Oracle的数据库(java创建oracle)
- java如何对map进行排序详解(map集合的使用)
- java使用pdfbox操作pdf文件示例