您的专属咨询通道

  • 求职者通道

    简历石沉大海,面试屡战屡败,你得从自身想想原因
  • 在职者通道

    跳槽?转行?离开了学校但你还拥有学习的激情
  • 大学生通道

    大学生,学历技能于一身,你的就业没问题
  • 高中生通道

    作为高中生的你,大学不是唯一的成才之路

在线QQ咨询

  • 点击这里给我发消息 学费咨询
  • 点击这里给我发消息 就业咨询
  • 点击这里给我发消息 学历咨询
  • 点击这里给我发消息 课程咨询

校园地址

  • 报名咨询: 0512-65566661
  • 地址:苏州市阊胥路483号
  • 创元科技园6号 楼1层

java中资源获取

发布时间:2011-06-09 13:07:05  作者:SystemMaster   来源:
在开发java程序的过程中,我们经常要做的一件事就是获取资源。那么什么是资源呢?说白了,在计算机里那就是一堆数据。只是这堆数据对我们的 java程序有多种表现形式,一般来说有File,URL,InputStream等等。而单就文件这一项就有很多种:配置文件,java类文件,jps 文件,图片、css、js文件等等。面对这林林总总的资源,我们在设计一个读取资源的接口时,就需要针对不同形式的资源提供方法,这样就导致我们的接口还是与实际的资源形式绑定在一起,未能完全的抽象。另外,在java程序中资源的存放位置也是各异的。有的存放在classpath中,有的存放在文件系统中,有的存放在web应用中。而对于不同位置的资源,java程序获取这些资源的方法各有不同。
A、获取classpath中的资源:
Java代码
URL url = this.getClass().getResource("resource_name");  
URL url = this.getClass().getClassLoader().getResource("resource_name");  
URL url = Thread.currentThread().getContextClassLoader().getResource("resource_name"); 
  URL url = this.getClass().getResource("resource_name");
  URL url = this.getClass().getClassLoader().getResource("resource_name");
  URL url = Thread.currentThread().getContextClassLoader().getResource("resource_name");
那么在jdk中为什么又提供了三种方式来获取classpath下的资源呢?这其中是有些来头的。
第一行代码中是利用Class类的实例来获取,第二行代码是使用加载当前类的classloader来获取。看下jdk中的源代码会发现class类的实例最后还是委托加载他的classloader来获取资源的。
Java代码
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);  
    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);
    }
从上面的代码中可以看出,对于资源的加载并没有像类加载所采用的双亲委托机制。而是当前类的classloader不为null的情况下先从当前类的 classloader中加载资源。而只有当前类的classloader为null的时候才从system classloader中去加载资源。这样可以方便我们自定义配置类覆盖一些默认配置。当然,j2se应用中如果没有特别定制classloader时,我们自己写的类都是被system classloader加载的。到底利用class去获取资源和利用classloader去获取资源有什么区别呢?区别就在 resolveName(name)这个方法中。两种方式对于资源名称的表示方式不同。下面是一个简单的包结构,/表示类路径的根
/
|-com.cn.test
   |-Test.class
   |-test2.txt 
|-test1.txt
Java代码
// 获取与当前类在同一个包下的资源  
URL url1 = this.getClass().getResource("test2.txt");  
// 获取com.cn.test包下的资源,需加/  
URL url2 = this.getClass().getResource("/com/cn/test/test2.txt");  
// 获取类路径根下的资源  
URL url3 = this.getClass().getClassLoader().getResource("test1.txt");  
// 获取包com.cn.test包下的资源  
URL url4 = this.getClass().getResource("com/cn/test/test2.txt"); 
  // 获取与当前类在同一个包下的资源
  URL url1 = this.getClass().getResource("test2.txt");
  // 获取com.cn.test包下的资源,需加/
  URL url2 = this.getClass().getResource("/com/cn/test/test2.txt");
  // 获取类路径根下的资源
  URL url3 = this.getClass().getClassLoader().getResource("test1.txt");
  // 获取包com.cn.test包下的资源
  URL url4 = this.getClass().getResource("com/cn/test/test2.txt");

而第三利用当前线程的contextClassLoader来获取资源的解释可以参考我的另一篇
B、获取文件系统中的资源
Java代码
// 1、获得File对象  
File file = new File("test.txt");  
// 2、获得File对象的字节流  
InputStream in = new FileInputStream(file); 
  // 1、获得File对象
  File file = new File("test.txt");
  // 2、获得File对象的字节流
  InputStream in = new FileInputStream(file);
值得注意的是在File的构造函数File(String name) 中的name参数可以是相对路径和绝对路径。相对路径是相对于System.getProperties("user.dir")的。
C、获取web应用中的资源
Java代码
servletContext.getResourceAsStream(resource_name); 
servletContext.getResourceAsStream(resource_name);
resource_names为相对于webroot的路径表示。例如获取web.xml,resource_name表示为"/WEB-INF/web.xml"
    面对上面介绍的各种资源表现形式和存放位置,难道java中就没有提供一个统一处理方式吗?有,java.net.URL。
从名称上来看 URL(Uniform Resource Locator) 统一资源定位器。看起来很好很强大。但很多时候使用它并不能定位到我们需要的资源。
    首先,它jdk中体统的URL能访问的协议非常有限(当然可以进行扩展,不过很麻烦);常用的有http,file,ftp等等。并没有提供对classpath和servletContext中的资源的获取方法。
    另外,它没有提供判断资源是否存在的方法。每次只有等我们真正去获取资源的时候抛出异常才能知道资源无法获取。
    其次,URL这个类的职责未划分清楚,既用来表示资源有用来获取其资源。

苏州北大青鸟报名咨询:0512-65566661 65566662 备案许可证号:苏ICP备09076008号 苏州北大青鸟阊胥路标准化校区 | 苏州苏香信息技术有限公司 办学许可证号:劳社民3205013000041号 地址:苏州市阊胥路483号创元科技园6号楼1层(干将西路友通数码港向北100米) 苏州北大青鸟交通路线:6、7、 7路区间、64、70、88、262、300、303、304、307、318、332、333、333路龙池专线、522、800、921、932、949.(小日晖桥北站) 技术支持:苏州天络科技
在线客服
在线客服系统