SpringBoot读取Resource目录文件的五种常见方式
目录
- 1. 前言
- 2. 读取Resource文件的五种常见方式
- 2.1 使用 ClassPathResource(推荐)
- 2.2 使用 ResourceLoader
- 2.3 使用 @Value 注解
- 2.4 使用 ResourceUtils
- 2.5 通过 getResourceAsStream
- 补充:读取Properties文件
- 3. 完整实战案例:读取CSV文件并处理
- 3.1 创建测试文件
- 3.2 创建CSV处理器
- 3.3 创建Controller测试
- 4. 常见问题解决方案
- 问题1:文件路径错误
- 问题2:打包后文件读取失败
- 问题3:读取Resource目录文件中文乱码
- 5. 总结
1. 前言
在Spring Boot开发中,我们经常需要读取src/main/resources
目录下的文件,src/main/resources
目录下通常存放配置文件、模板、静态资源、SQL脚本等,如何在运行时读取这些资源,是每个Java开发者必须掌握的技能。
比如下面的Spring Boot项目中,资源文件的存储位置:
src/ └── main/ └── resources/ ├── static/ # 静态资源 ├── templates/ # 模板文件 ├── config/ # 配置文件 └── data/ # 数据文件
本文博主将将从多种角度详细介绍在 Spring Boot
中读取类路径(classpath
)下资源的方法,并给出完整的代码示例,相信小伙伴们看完一定能掌握这个技巧!
2. 读取Resource文件的五种常见方式
2.1 使用 ClassPathResource(推荐)
Spring 提供了 ClassPathResourandroidce
,可直接从类路径获取资源
import org.springframework.core.io.ClassPathResource; import org.springframework.util.FileCopyUtils; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; public class ResourceReader { public String readwithClassPathResource(String filePath) throws Exception { ClassPathResource resource = new ClassPathResource(filePath); try (InputStreamReader reader = new InputStreamReader( resource.getInputStream(), StandardCharsets.UTF_8)) { return FileCopyUtils.copyToString(reader); } } }
测试示例:
String content = readWithClassPathResource("data/sample.txt"); System.out.println(content);
2.2 使用 ResourceLoader
ResourceLoader
是 Spring
上下文提供的通用资源加载接口,支持多种前缀(classpath:、file:、http: 等)
import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Component; import java.io.IOException; import java.nio.charset.StandardCharsets; @Component public class ResourceService { private final ResourceLoader resourceLoader; public ResourceService(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public String readWithResourceLoader(String location) throws Exception { Resource resource = resourceLoader.getResource(location); try (InputStream in = resource.getInputStream()) { byte[] bytes = in.readAllBytes(); return new String(bytes, StandardCharsets.UTF_8); } } }
测试示例:
// 读取 classpath 下的 sample.txt String text = resourceLoaderService.readWithResourceLoader("classpath:data/sample.txt");
2.3 使用 @Value 注解
如果只是读取小片段文本或 URL,可直接在字段或方法参数上使用 @Value
import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import java.io.IOException; import java.nio.charset.StandardCharsets; @Component public class ValueResourceReader { @Value("classpath:data/sample.txt") private Resource configFile; public String readConfig() throws IOException { return new String(configFile.getInputStream().readAllBytes(), StandardCharsets.UTF_8); } }
2.4 使用 ResourceUtils
ResourceUtils
是 Spring
内置的一个工具类, 可以将类路径资源转换为 File
或 URL
,适用于需要 java.io.File 操作的场景
import org.springframework.stereotype.Service; import org.springframework.util.ResourceUtils; import java.io.File; import java.nio.file.Files; import java.nio.charset.StandardCharsets; @Service public class ResourceUtilsService { public String readWXTCMysithResourceUtils(String location) throws Exception { // location 形如:"classpath:data/sample.txt编程客栈" File file = ResourceUtils.getFile(location); byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, StandardCharsets.UTF_8); } }
2.编程客栈5 通过 getResourceAsStream
最原生的方式:通过 Class
或 ClassLoader
的 getResourceAsStream
import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.stream.Collectors; @Service public class NativeStreamService { public String readWithGetResourceAsStream(String path) { try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(path); BufferedReader reader = new BufferedReader( new InputStreamReader(in, StandardCharsets.UTF_8))) { return reader.lines().collect(Collectors.joining(System.lineSeparator())); } catch (Exception e) { throw new RuntimeException("读取资源失败", e); } } }
补充:读取Properties文件
有小伙伴说,读取的配置文件是Properties
文件,要如何来读取?下面博主做一个补充,依然使用 ClassPathResource
读取文件
import org.springframework.core.io.ClassPathResource; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class PropertiesReader { public Properties readProperties(String filePath) throws IOException { ClassPathResource resource = new ClassPathResource(filePath); try (InputStream input = resource.getInputStream()) { Properties properties = new Properties(); properties.load(input); return properties; } } }
3. 完整实战案例:读取CSV文件并处理
下面我们通过一个实战案例,来加深小伙伴的理解
3.1 创建测试文件
在 src/main/resources/data/
下创建users.csv
:
id,name,email 1,张三,zhangsan@example.com 2,李四,lisi@example.com
3.2 创建CSV处理器
import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; @Service public class CsvService { public List<User> parseCsv(String filePath) throws Exception { ClassPathResource resource = new ClassPathResource(filePath); List<User> users = new ArrayList<>(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(resource.getInputStream()))) { // 跳过标题行 String line = reader.readLine(); while ((line = reader.readLine()) != null) { String[] parts = line.split(","); if (parts.length == 3) { users.add(new User( Integer.parseInt(parts[0]), parts[1], parts[2] )); } } } return users; } public static class User { private int id; private String name; private String email; // 构造方法、getters和toString } }
3.3 创建Controller测试
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class CsvController { private final CsvService csvService; public CsvController(CsvService csvService) { this.csvService = csvService; } @GetMapping("/users") public List<CsvService.User> getUsers() throws Exception { return csvService.parseCsv("data/users.csv"); } }
启动应用后访问:http://localhost:8080/users
输出结果
看到输出如下数据证明已经读取成功
[ { "id": 1, "name": "张三", "email": "zhangsan@example.com" }, { "id": 2, "name": "李四", "email": "lisi@example.com" } ]
4. 常见问题解决方案
问题1:文件路径错误
错误信息:java.io.FileNotFoundException: class path resource [xxx] cannot be opened because it does not exist
解决方案:
检查文件是否在src/main/resources目录下
使用正确路径(区分大小写)文件路径前不要加/(正确:data/file.txt,错误:/data/file.txt)
问题2:打包后文件读取失败
错误信息:FileNotFoundException when reading from JAR
解决方案:
使用ClassPathResource而不是File
避免使用new File(“classpath:…”)语法使用getResourceAsStream()方法
问题3:读取Resource目录文件中文乱码
解决方案:
// 明确指定UTF-8编码 new InputStreamReader(resourwww.devze.comce.getInputStream(), StandardCharsets.UTF_8);
5. 总结
Spring Boot
提供了多种灵活的方式来读取resource
目录下的文件。根据不同场景选用最合适的方式:
- 如果需要
Spring
统一管理,推荐ResourceLoader
; - 若只是简单注入小文件,可选 @Value;
- 如果需要操作 File,可用 ResourceUtils。
以上就是SpringBoot读取Resource目录文件的五种常见方式的详细内容,更多关于SpringBoot读取Resource目录文件的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论