揭秘!Spring Boot读取类路径下文件的有效办法
🌷 古代能成就伟大事业的人,不仅有超凡的才能,也必定有坚韧不拔的意志
🎐 个人CSND主页——Micro麦可乐的博客🐥《Docker实操教程》专栏以最新的Centos版本为基础开展Docker实操教学,从入门到实战
🌺《RabbitMQ》专栏于19年编写,主要讲解用JAVA开发RabbitMQ的系列教程,从基础到项目实战
🌸《设计模式》专栏以实际生活场景为案例进行讲解,让大家对设计模式有更清晰的认识
🌛《开源项目》本专栏主要介绍当下热门的开源项目,帮助大家快速了解并轻松上手使用
🍎
《前端技术》专栏侧重实战,介绍日常开发中前端应用的一些功能和技巧,均有完整代码示例✨《开发技巧》本专栏包含各类系统的设计原理及注意事项,还分享日常开发的功能小窍门
💕《Jenkins实战> 专栏主要介绍Jenkins+Docker的实战教学,助你快速掌握项目CI/CD,是2024年最新实战教程
🌞《Spring
Boot》专栏主要讲解日常工作项目中常应用的功能和技巧,代码示例完整
👍《Spring
Security》专栏中我们将逐步深入Spring
Security的各项技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能给大家带来一定帮助!欢迎关注、评论互动~
看完!我不允许你还不清楚Spring Boot如何读取类路径下文件
- 1. 前言
- 2. 读取类路径文件的五种常见方式
-
-
- 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:读取类路径文件中文乱码
-
- 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. 读取类路径文件的五种常见方式
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:读取类路径文件中文乱码
解决方案:
// 明确指定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表达式!记得收藏起来哦~
文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/13112.html