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

mpfshine

mpfshine

2016-02-19 10:11

下面图老师小编要跟大家分享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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

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

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

获取到应用类加载器之后,就是获取资源文件了,调用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的加载路径。

展开更多 50%)
分享

猜你喜欢

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

编程语言 网络编程
Java加载资源文件时的路径问题的解决办法

QQ占用CPU资源过高问题的解决办法

电脑入门
QQ占用CPU资源过高问题的解决办法

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

播放资源文件文件中的声音

编程语言 网络编程
播放资源文件文件中的声音

Delphi中使用资源文件

编程语言 网络编程
Delphi中使用资源文件

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Java小程序源文件的组成

编程语言 网络编程
Java小程序源文件的组成

资源文件在DELPHI中的使用

Delphi
资源文件在DELPHI中的使用

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

Java for循环的几种用法分析

Java for循环的几种用法分析

AJAX架构之Dojo篇

AJAX架构之Dojo篇
下拉加载更多内容 ↓