Java获取资源文件方式,需要注意的地方,maven或者gradle环境下获取不到包下资源问题

项目编译后资源文件夹分析

一般的Java项目目录下有两部分静态资源文件夹:

  1. java 文件夹。
  2. resources 文件夹。
    在这里插入图片描述

项目编译时期会将这两个文件夹下的文件分别按照包层级(文件夹层级)和文件夹层级关系放到target/classes文件夹下
在这里插入图片描述
通过这些分析可以认识到:获取包目录下的资源文件就是包路径加上文件名,获取resources下的资源文件直接使用文件名,如果resources下有文件夹毫无疑问需要加上文件夹名。

获取资源方式

1. 通过当前线程的上下文类加载器或者当前类的类加载器获取资源

Thread.currentThread().getContextClassLoader().getResourceAsStream("com/freesky/io/ch.properties");
ResourcesTest.class.getClassLoader().getResourceAsStream("com/freesky/io/ch.properties");

在这里插入图片描述
这种方式传入的path就是文件的包路径,前面不要加“/”因为Java不会对这个“/”做任何处理。

2. 通过Class.getResourceAsStream(String name)方法获取资源

ResourcesTest.class.getResourceAsStream("/com/freesky/io/ch.properties")

注意,这种方式前面必须加“/”,是什么原因呢?跟代码看看

public InputStream getResourceAsStream(String name) {
    //该方法对传入的路径进行了处理
    name = resolveName(name);
    ClassLoader cl = getClassLoader0();
    if (cl==null) {
        // A system class.
        return ClassLoader.getSystemResourceAsStream(name);
    }
    return cl.getResourceAsStream(name);
}

代码:name = resolveName(name);对传入的路径进行了处理

private String resolveName(String name) {
    if (name == null) {
        return name;
    }
    //判断是否是以“/”开头
    if (!name.startsWith("/")) {
    	//不是以“/”开头逻辑处理
        Class<?> c = this;
        while (c.isArray()) {
            c = c.getComponentType();
        }
        //获取当前类Class的的名称
        //com.freesky.io.ResourcesTest
        String baseName = c.getName();
        //下面的逻辑就是获取该类的包路径,拼加在name上
        //结果就是这样:com/freesky/io/com/freesky/io/ch.properties
        //这个路径根本就不存在
        int index = baseName.lastIndexOf('.');
        if (index != -1) {
            name = baseName.substring(0, index).replace('.', '/')
                +"/"+name;
        }
    } else {
    	//如果是以“/”开头就直接去掉“/”
        name = name.substring(1);
    }
    return name;
}

maven或者gradle项目下用这种方式获取的文件流为空

在这里插入图片描述
通过上图可以发现编译后的资源文件夹下找不见需要获取的文件“ch.properties”,这是因为maven项目将包路径不看做资源文件夹,需要加上以下配置将包路径设置为资源文件夹,并可以指定文件格式:

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.properties</include>
        </includes>
        <filtering>false</filtering>
    </resource>
</resources>

再次编译:
在这里插入图片描述
gradle的配置如下:

sourceSets {
    main {
        //指定资源文件夹
        resources.srcDirs = ['src/main/resources', 'src/main/java']
    }
}

猜你喜欢

转载自blog.csdn.net/qwqw3333333/article/details/104802235