欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于获取资源文件,Class.getResource和ClassLoader.getResource的区别

程序员文章站 2022-07-25 23:28:12
原文同步发表至个人博客【夜月归途】 原文链接:http://www.guitu18.com/se/java/2019-02-22/29.html 作者:夜月归途 出处:http://www.guitu18.com/ 本博客中未标明转载的文章归作者夜月归途和博客园所有。 欢迎转载,但未经作者同意必须保 ......

原文同步发表至个人博客

原文链接:

在java中经常会需要读取各种各样的配置文件,在获取资源时,一般会用到 class.getresource()classloader.getresource() ;

那么这两种方式在获取资源文件时有什么相同或者不同的地方呢?

先贴上代码目录结构:

┌─src
│  └─main
│     └─java
│        └─com.guitu18.blog
│           ├─classpath
│           │  └─getresourcetest.java
│           └─springbootapplication.java
└─resource
   ├─mapper
   │   └─blogdao.xml
   └─confog.properties

class.getresource()

测试代码,先看 this.getclass().getresource()
代码的输出结果我直接贴在代码的上一行了,下同。

@test
public void classgetresource() {
    // file:/e:/repo/guitu-blog/target/test-classes/com/guitu18/blog/classpath/
    system.out.println(this.getclass().getresource(""));
    // file:/e:/repo/guitu-blog/target/test-classes/
    system.out.println(this.getclass().getresource("/"));
}

可以看出,getresource("") 获取的是当前类所在包的路径,而 getresource("/") 获取的是 classpath 根路径;

继续测试,我们获取目录下的文件:

@test
public void classgetproperties() {
    // file:/e:/repo/guitu-blog/target/classes/config.properties
    system.out.println(this.getclass().getresource("/config.properties"));
    // null
    system.out.println(this.getclass().getresource("blogdao.xml"));
    // file:/e:/repo/guitu-blog/target/classes/mapper/blogdao.xml
    system.out.println(this.getclass().getresource("/mapper/blogdao.xml"));
    /**
     * .java文件在编译后编程.class,所以这里参数传的文件名是.class结尾
     */
    // file:/e:/repo/guitu-blog/target/classes/com/guitu18/blog/classpath/getresourcetest.class
    system.out.println(this.getclass().getresource("getresourcetest.class"));
    // file:/e:/repo/guitu-blog/target/classes/com/guitu18/blog/springbootapplication.class
    system.out.println(this.getclass().getresource("../springbootapplication.class"));
    // file:/e:/repo/guitu-blog/target/classes/com/guitu18/blog/classpath/getresourcetest.class
    system.out.println(this.getclass().getresource("../classpath/getresourcetest.class"));
}

输出结果显示:

  1. 当以 "/" 开头时,是从 classpath 路径开始匹配资源;
  2. 当不以 "/" 开头时,是从当前类所在包的路径开始匹配资源;
  3. 两种方式都可以通过 "/""../" 在文件夹上下层路径切换;

另外,在获取文件时,我们还可以通过 getresourceasstream 直接获取文件输入流,如:

inputstream inputstream = this.getclass().getresourceasstream("/config.properties");

getresourceasstream()getresource() 在获取文件流和文件路径时,路径选择机制是一样的。

classloader.getresource()

接着看 this.getclass().getclassloader().getresource ,上代码:

@test
public void classloadergetresource() {
    // file:/e:/repo/guitu-blog/target/test-classes/
    system.out.println(this.getclass().getclassloader().getresource(""));
    // null
    system.out.println(this.getclass().getclassloader().getresource("/"));
}

在使用 classloader().getresource 获取路径时,不能以 "/" 开头,且路径总是从 classpath 根路径开始;

@test
public void classloadergetproperties() {
    /**
     * 同样可以通过"/"或"../"在文件夹上下层路径切换
     */
    // file:/e:/repo/guitu-blog/target/classes/config.properties
    system.out.println(this.getclass().getclassloader().getresource("config.properties"));
    // null
    system.out.println(this.getclass().getclassloader().getresource("blogdao.xml"));
    // file:/e:/repo/guitu-blog/target/classes/mapper/blogdao.xml
    system.out.println(this.getclass().getclassloader().getresource("mapper/blogdao.xml"));
    /**
     * 同class.getresourceasstream()一样,我们还可以通过classloader.getresourceasstream()直接获取文件输入流
     * classloader.getresourceasstream()和classloader.getresource()在获取文件流和文件路径时,路径选择机制也是一样的
     */
    inputstream inputstream = this.getclass().getclassloader().getresourceasstream("config.properties");
}

这里跟上面差别不大,所以直接把结果写在代码注释中了, classloader().getresource 只能从 classpath 开始获取资源,同样也能使用getresourceasstream() 获取文件输入流,且路径机制一样;

总结

  1. class.getresource() 可以从当前 class 所在包的路径开始匹配获取资源,也可以从 classpath 根路径开始匹配获取资源;
  2. classloader().getresource() 只能从 classpath 根路径开始匹配获取资源;
  3. class.getresource() 从当前包所在路径获取资源时不能以 "/" 开头,而从 classpath 根路径获取资源时必须以 "/" 开头;
  4. classloader().getresource() 不能以 "/" 开头,且路径总是从 classpath 根路径开始;
  5. 它们都能通过 getresourceasstream() 方法获取对应路径文件的输入流,文件路径匹配机制和其 getresource() 方法一样;