classpath和读取resources目录下的文件

最近在springboot+maven的项目中去读取资源文件的时候,报了找不到文件的错误。由此展开了对maven项目编译前和编译后的目录结构的了解,以及对java的classpath的理解。

首先,由Maven构建的web工程,java代码放在src/main/java路径下,资源(配置文件等)放在src/main/resources路径下,当构建jar包 或 war包时,JVM虚拟机会自动编译java文件为class文件存放在 target/classes目录下,resource资源下的文件会原封不动的拷贝一份到 target/classes 目录下:而我们一般取的classpath就是target/classes目录

你可以通过这种方式打印你的calsspath

A.class.getClassLoader().getResource("").getPath();

这里又引出一个话题,我们可以根据两种不同的方式去获取Resources下的文件

1、class.getResource()

import org.junit.jupiter.api.Test;

public class ResourceTestDemo {

    @Test
    void getResourceTest(){
        System.out.println(ResourceTestDemo.class.getResource(""));
        System.out.println(ResourceTestDemo.class.getResource("/"));
       }

打印结果:



1、file:/Users/username/Documents/TestDev/MyTraining/XUnit/ResourceTest/target/classes/3.txt
2、file:/Users/username/Documents/TestDev/MyTraining/XUnit/ResourceTest/target/classes/test/2.txt


结果分析:
1、getResource("")不带"/“时候是从当前类所在包路径去获取资源
2、getResource("/")带”/"时候是从classpath的根路径获取

2、getClassLoader().getResource()

@Test
 void getClassLoaderResourceTest(){
     System.out.println(ResourceTestDemo.class.getClassLoader().getResource(""));
     System.out.println(ResourceTestDemo.class.getClassLoader().getResource("/"));
 }

打印结果:

file:/Users/qinzhen/Documents/TestDev/MyTraining/XUnit/ResourceTest/target/test-classes/
null

class.getResource()不带"/"时候是从当前类所在包路径去获取资源
class.getResource()带"/"时候是从classpath的根路径获取
class.getResource()本质上也是调用了getClassLoader,只是封装了一层方便了我们使用而已
getClassLoader().getResource("")不带"/"时候是从classpath的根路径获取
getClassLoader().getResource("/")路径中无法带有"/"
getResourceAsStream() 方法仅仅是获取对应路径文件的输入流,在路径的用法上与getResource()一qu

4、批量读取:

如果想要批量读区resource下的文件呢?

Resource[] resources = ResourceTestDemo.class.getClassLoader().getResources("validator-config/*.xml");
for (int i = 0; i < resources.length; i++) {
    InputStream inputStream = resources[i].getInputStream();
    String xmlContent = IOUtils.toString(inputStream, "UTF-8");
    System.out.println("content" + i + "=" + xmlContent);
}

5、如果配置文件中要引用这个文件的路径呢?

用classpath:xxx.xml 就可以了(xxx.xml放在resources目录下)。注意是springboot的项目

如果还是取不到,看看你的maven工程的pom文件是否做了过滤文件,比如.keystore文件


 <build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>*.keystore</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <includes>
                <include>*.keystore</include>
            </includes>
        </resource>
    </resources>
</build>

 

 

 

 

 

### 如何在Spring Boot中读取resources目录下的文件 在Spring Boot应用程序中,`resources` 文件夹是一个特殊的位置,通常用于存储配置文件、静态资源其他运行时所需的文件。要从 `resources` 文件夹中读取文件,可以使用多种方法。 #### 使用 ClassLoader 的 getResourceAsStream 方法 一种常见的方法是通过 Java 的 `ClassLoader` 类来获取文件流。此方式适用于大多数场景,尤其是当目标文件位于类路径下时。下面展示了一个简单的例子: ```java import java.io.InputStream; import org.springframework.core.io.ClassPathResource; public class FileReaderExample { public static void readFileFromResources() throws Exception { InputStream inputStream = new ClassPathResource("example.txt").getInputStream(); try (var reader = new java.util.Scanner(inputStream)) { while(reader.hasNextLine()) { System.out.println(reader.nextLine()); } } catch(Exception e){ throw new RuntimeException("Failed to read file", e); } } } ``` 上述代码片段展示了如何利用 `ClassPathResource` 来加载名为 `example.txt` 的文件[^3]。注意,这里的文件名应相对于 `src/main/resources` 路径指定。 另一种替代方案涉及直接调用 `Thread.currentThread().getContextClassLoader().getResourceAsStream()` 函数实现相同功能: ```java InputStream inputStream = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("example.txt"); if(inputStream == null){ throw new IllegalArgumentException("File not found!"); } // 继续处理输入流... ``` 这两种技术都可以有效地访问嵌套于 JAR 或 WAR 包内部的资源文件,在开发阶段以及部署后的生产环境中均适用。 #### 配置与注意事项 如果发现尝试读取特定文件失败(即返回null),可能是因为该文件未正确定位到classpath目录或者拼写错误等原因造成的。确认所请求的相对路径无误非常重要。 另外需要注意的是,对于大型二进制数据或其他不适合一次性载入内存的数据对象,则需考虑采用分块传输等方式优化性能表现;而对于纯文本型的小规模文档来说,上面提到的方法已经足够满足需求了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值