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

Java获取项目中的文件

程序员文章站 2022-04-30 09:12:40
...

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

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

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

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

粗解

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

    1
    2
    3
    4
    
    // 方式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")

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

    这两条语句的输出:

    1
    2
    3
    
    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()两种方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    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. 读取资源文件内容方式

    1
    2
    3
    4
    5
    6
    
    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);
    }
    

整个测试文件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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);

    }

}