spring项目中src\main\resources和src\test\resources下的加载文件问题

src/main/java:里面的java文件只能直接加载src/main/resources下的资源,不能直接加载src/test/resources下的资源;
src/test/java: 里面的java文件既能加载src/test/resources下的资源,又能加载src/main/resources下的资源,当两个resources下都有要加载的同名资源时候,优先选择src/test/java下的资源;

原文链接:https://blog.csdn.net/liangwenmail/article/details/72520523

<think>好的,我需要帮助用户在Spring Boot项目中读取resources文件夹下的文件,并且要同时兼容源码运行打包后的JAR文件。首先,我得回顾一下用户提供的引用内容,看看有哪些方法已经被提到过。 用户提到了四种方法,前四种在项目JAR中都能用,第五种只能在项目文件中使用。引用[1]提到用ClassLoaderSpringResourceUtils/ResourceLoader。引用[4]则补充了类加载器的方法,并提到ApplicationHome获取路径可能有问题。那用户的需求是找到一种兼容的方法,所以需要综合考虑这些方法。 首先,ClassLoader的getResourceAsStream方法应该是可靠的,因为它不依赖文件路径,而是通过类路径加载资源。这在JAR包内也能工作,因为JAR中的资源会被类加载器视为流。例如,使用Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")。这样可以避免文件系统路径的问题,适用于JAR环境。 其次,SpringResourceLoader也是一个好选择,因为它抽象了资源的位置,无论是类路径、文件系统还是URL。通过注入ResourceLoader,然后使用resourceLoader.getResource("classpath:file.txt")获取资源,再转换成InputStream。这种方法在Spring环境中更集成,可能更方便。 另外,用户提到引用[4]中的方法1用ApplicationHome获取路径,但需要注意这种方法在JAR中可能无法正确访问资源文件,因为JAR内的文件不是单独存在的,而是打包在内部的。所以应该避免使用文件系统路径的方式,而是用流的方式读取。 还需要注意编码问题,比如在读取文件时指定正确的字符集,避免乱码。例如,使用InputStreamReader时指定UTF-8。 测试部分,用户提供的引用[2]中的测试代码可以借鉴,确保在单元测试中也能正确读取资源。可能需要编写测试用例,验证在两种环境下都能成功读取文件。 总结下来,推荐使用类加载器或SpringResourceLoader来获取资源流,这样无论在源码运行还是打包后都能正常工作。同时,避免使用基于文件路径的方法,因为JAR中的资源不是以文件形式存在的。</think>在Spring Boot项目中读取resources目录下的文件,并确保源码运行打包成JAR后兼容,可以通过以下方法实现: ### 一、核心方法推荐 #### 1. 类加载器方式(ClassLoader) ```java // 获取文件流(推荐) InputStream inputStream = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("files/example.txt"); // 读取文件内容 try (BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { String content = reader.lines().collect(Collectors.joining("\n")); } ``` #### 2. Spring资源加载器(ResourceLoader) ```java @Autowired private ResourceLoader resourceLoader; public void readFile() throws IOException { Resource resource = resourceLoader.getResource("classpath:files/example.txt"); InputStream inputStream = resource.getInputStream(); // 读取内容同上 } ``` ### 二、方法对比 | 方法 | 源码环境 | JAR包环境 | 是否需要绝对路径 | 是否依赖Spring | |--------------------|----------|-----------|------------------|----------------| | ClassLoader | ✔️ | ✔️ | ❌ | ❌ | | ResourceLoader | ✔️ | ✔️ | ❌ | ✔️ | | ResourceUtils | ✔️ | ❌ | ✔️ | ✔️ | | Files.newInputStream | ✔️ | ❌ | ✔️ | ❌ | ### 三、关键注意事项 1. **禁止使用绝对路径**:JAR包内文件不以独立文件形式存在,`File`对象会失效[^4] 2. **统一字符编码**:建议显式指定`StandardCharsets.UTF_8` 3. **资源关闭**:必须使用try-with-resources确保流关闭 4. **路径格式**:以`classpath:`开头表示资源路径,不使用`file:`前缀 ### 四、验证测试(兼容JAR源码) ```java @SpringBootTest public class ResourceReadTest { @Test public void testClassLoader() { InputStream is = getClass().getClassLoader() .getResourceAsStream("application.yml"); assertNotNull(is); // 验证配置文件的读取 } @Autowired private ResourceLoader resourceLoader; @Test public void testResourceLoader() throws IOException { Resource resource = resourceLoader.getResource("classpath:static/icon.png"); assertTrue(resource.exists()); // 验证二进制文件的读取 } } ``` ### 五、原理解析 Spring Boot通过`LaunchedURLClassLoader`实现JAR包内资源的加载,将JAR文件视为虚拟文件系统[^3]。当使用`getResourceAsStream`时,实际是通过`JarURLConnection`访问压缩包内的条目[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值