看完!我不允许你还不知道Spring Boot如何读取Resource目录文件
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 提供了 ClassPathResource
,可直接从类路径获取资源
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 readWithResourceUtils(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(resource.getInputStream(), StandardCharsets.UTF_8);
5. 总结
Spring Boot
提供了多种灵活的方式来读取resource
目录下的文件。根据不同场景选用最合适的方式:
- 如果需要
Spring
统一管理,推荐ResourceLoader
; - 若只是简单注入小文件,可选 @Value;
- 如果需要操作 File,可用 ResourceUtils。
掌握这些方法,能让小伙伴们在处理配置、模板、静态资源等场景时更得心应手,如果你在实践过程中有任何疑问或更好的扩展思路,欢迎在评论区留言,最后希望大家 一键三连 给博主一点点鼓励!
专栏最新回顾
【01】ThreadLocal的原理以及实际应用技巧详解 - 如何在身份认证场景Token中传递获取用户信息
【02】基于MyBatis-Plus Dynamic-Datasource实现 SaaS 系统动态租户数据源管理
【03】基于nacos实现动态线程池设计与实践:告别固定配置,拥抱弹性调度
【04】Java常用加密算法详解与实战代码 - 附可直接运行的测试示例
【05】Java synchronized 锁机制深度解析与实战指南 - 银行转账案例
【06】还在为线上BUG苦苦找寻?试试IntelliJ IDEA远程调试线上Java程序
【07】使用 Apache Commons Exec 自动化脚本执行实现 MySQL 数据库备份
【08】JAVA开发中几个常用的lambda表达式!记得收藏起来哦~