Java获取项目中的文件

Class.getResource()与ClassLoader.getResource()的区别

Class.getResource()是指AAA.class.getResource()

  1. Class.getResource(String name):在当前class类的同一路径下查找资源

  2. ClassLoader.getResource(String name):在根目录下查找该资源文件,即"/"或classpath目录

粗解

  1. 在当前项目目录下查找指定的文件,此方式只能加载当前项目classpath下的文件,用.表示当前目录,不能以/开头,会报错

    // 方式1
    URL url = ClassLoader.getSystemResource(".");
    // 方式2
    url = LoaderResourceTest.class.getClassLoader().getResource(".");
    

    url会输出当前class文件所在的根目录,比如当前我输出的结果就是file:/Users/chuan/Documents/projects_code/java-project/demo/demo-core/target/classes/

  2. 以当前类所在的目录为基础,在当前目录查找并加载指定名称的资源文件,比如当前类LoaderResourceTest在项目的cc.kevinlu.demo.core.loader包中,若是我们以LoaderResourceTest.class.getResource("LoaderT.class")的方式加载一个文件,则首先会在cc.kevinlu.demo.core.loader包中查找LoaderT.class文件,若查找不到则返回null,如果我们想要加载其他包中的文件,则可以使用"/"开头并加上文件在项目中的完整包路径,比如LoaderResourceTest.class.getResource("/cc/kevinlu/demo/core/gof/facade/FacadeTest.class")

    // 获取当前类所在的包目录
    url = LoaderResourceTest.class.getResource(".");
    
    // 获取其他包内的文件
    url = LoaderResourceTest.class.getResource("/cc/kevinlu/demo/core/gof/facade/FacadeTest.class");
    

    这两条语句的输出:

    file:/Users/chuan/Documents/projects_code/java-project/demo/demo-core/target/classes/cc/kevinlu/demo/core/loader/
    
    file:/Users/chuan/Documents/projects_code/java-project/demo/demo-core/target/classes/cc/kevinlu/demo/core/gof/facade/FacadeTest.class
    

    由此可以很明显的看出Class的getResource是获取当前类所在的包目录,如果不同的包中都有相同名称的资源文件,但是仅针对当前包可用,那么就可以使用这种方式去加载读取,不会出现读到其他目录的文件的情况,但是这仅受限于我们写的类,不适用于jar包中的。

  3. 如果我们想读取项目中引用的jar包内的文件,那么怎么办?其实和读取项目中自己写的文件是相同的办法,因为在系统启动的时候会将jar包中的文件加载到classpath目录下,所以读取方式一样的。

  4. 以上讲解的只是读取单个资源,那么要是想把所有匹配到的资源都获取到,则可以使用Class.getClassLoader().getResources()ClassLoader.getSystemResources()两种方式

    Enumeration<URL> urls = LoaderResourceTest.class.getClassLoader().getResources("META-INF/spring.factories");
    while (urls.hasMoreElements()) {
      System.out.println(urls.nextElement());
    }
    
    System.out.println("--ClassLoader.getSystemResources--");
    urls = ClassLoader.getSystemResources("META-INF/spring.factories");
    while (urls.hasMoreElements()) {
      System.out.println(urls.nextElement());
    }
    
  5. 读取资源文件内容方式

    InputStream is = LoaderResourceTest.class.getClassLoader().getResourceAsStream("META-INF/spring.factories");
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String line = null;
    while ((line = br.readLine()) != null) {
      System.out.println(line);
    }
    

整个测试文件代码

package cc.kevinlu.demo.core.loader;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;

import org.springframework.boot.admin.SpringApplicationAdminMXBean;

public class LoaderResourceTest {

    public static void main(String[] args) throws Exception {

        // 在当前项目目录下查找指定的文件,此方式只能加载当前项目classpath下的文件,用.表示当前目录,不能以/开头,会报错
        URL url = ClassLoader.getSystemResource(".");
        System.out.println(url);

        // 此方式和ClassLoader.getSystemResource一样
        url = LoaderResourceTest.class.getClassLoader().getResource(".");
        System.out.println(url);

        // 以当前类所在的目录为基础,在当前目录查找并加载指定名称的资源文件,比如当前类LoaderResourceTest在
        // 项目的cc.kevinlu.demo.core.loader包中,若是我们以LoaderResourceTest.class.getResource("LoaderT.class")的
        // 方式加载一个文件,则首先会在cc.kevinlu.demo.core.loader包中查找LoaderT.class文件,若查找不到则返回null,如果我们想要加载其他包中的文件,
        // 则可以使用/开头并加上文件在项目中的完整包路径,比如LoaderResourceTest.class.getResource("/cc/kevinlu/demo/core/gof/facade/FacadeTest.class")                                                                                              
        url = LoaderResourceTest.class.getResource(".");
        System.out.println(url);

        url = LoaderResourceTest.class.getResource("/cc/kevinlu/demo/core/gof/facade/FacadeTest.class");
        System.out.println(url);

        // 获取jar包内的文件有以下方式
        // 1. 使用Class.getClassLoader().getResource(),这种方式只能获取第一个匹配到的文件
        System.out.println("************");
        url = LoaderResourceTest.class.getClassLoader().getResource("META-INF/spring.factories");
        System.out.println(url);
        System.out.println("************");

        // 2. 使用Class.getResource(),这种方式也只能获取第一个匹配到的文件
        url = LoaderResourceTest.class.getResource("META-INF/spring.factories");
        System.out.println(url);

        // 3. 使用ClassLoader.getSystemResource()方法,这种也仅仅只是获取第一个匹配的文件
        url = ClassLoader.getSystemResource("META-INF/spring.factories");
        System.out.println(url);

        // 那我们如果想要获取到所有匹配到的文件要怎么办呢?那么就使用Class.getClassLoader().getResources(),这个方法会返回一个Enumeration<URL>实例,
        // 我们迭代返回的这个实例就可以读取所有匹配到的所有文件了,如果没有匹配到任何文件也可以大胆的去迭代,不用判空,因为在getResources方法中进行了非空封装
        System.out.println("-----");
        Enumeration<URL> urls = LoaderResourceTest.class.getClassLoader().getResources("META-INF/spring.factories");
        while (urls.hasMoreElements()) {
            System.out.println(urls.nextElement());
        }
        System.out.println("-----");
        urls = ClassLoader.getSystemResources("META-INF/spring.factories");
        while (urls.hasMoreElements()) {
            System.out.println(urls.nextElement());
        }
        System.out.println("-----");

        // 如果想要读取文件的具体内容,那么我们就要用到文件流了,常用的方法就是使用BufferedReader去读了
        // getResourceAsStream()方法,它相当于你用getResource()取得File文件后,再new InputStream(file)一样的结果
        InputStream is = LoaderResourceTest.class.getClassLoader().getResourceAsStream("META-INF/spring.factories");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        int i = 1;
        while (i == 1 && (line = br.readLine()) != null) {
            System.out.println(line);
            i++;
        }

        System.out.println("*******");
        url = SpringApplicationAdminMXBean.class.getResource(".");
        System.out.println(url);

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值