SpringBoot讀取Resource目錄文件的五種常見方式
1. 前言
在Spring Boot開發(fā)中,我們經(jīng)常需要讀取src/main/resources目錄下的文件,src/main/resources 目錄下通常存放配置文件、模板、靜態(tài)資源、SQL腳本等,如何在運行時讀取這些資源,是每個JAVA開發(fā)者必須掌握的技能。
比如下面的Spring Boot項目中,資源文件的存儲位置:
src/
└── main/
└── resources/
├── static/ # 靜態(tài)資源
├── templates/ # 模板文件
├── config/ # 配置文件
└── data/ # 數(shù)據(jù)文件
本文博主將將從多種角度詳細(xì)介紹在 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,可直接在字段或方法參數(shù)上使用 @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 內(nèi)置的一個工具類, 可以將類路徑資源轉(zhuǎn)換為 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. 完整實戰(zhàn)案例:讀取CSV文件并處理
下面我們通過一個實戰(zhàn)案例,來加深小伙伴的理解
3.1 創(chuàng)建測試文件
在 src/main/resources/data/ 下創(chuàng)建users.csv:
id,name,email 1,張三,zhangsan@example.com 2,李四,lisi@example.com
3.2 創(chuàng)建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()))) {
// 跳過標(biāo)題行
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;
// 構(gòu)造方法、getters和toString
}
}
3.3 創(chuàng)建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");
}
}
啟動應(yīng)用后訪問:http://localhost:8080/users
輸出結(jié)果
看到輸出如下數(shù)據(jù)證明已經(jīng)讀取成功
[
{
"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目錄下
使用正確路徑(區(qū)分大小寫)
文件路徑前不要加/(正確: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. 總結(jié)
Spring Boot提供了多種靈活的方式來讀取resource目錄下的文件。根據(jù)不同場景選用最合適的方式:
- 如果需要
Spring統(tǒng)一管理,推薦ResourceLoader; - 若只是簡單注入小文件,可選 @Value;
- 如果需要操作 File,可用 ResourceUtils。
以上就是SpringBoot讀取Resource目錄文件的五種常見方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot讀取Resource目錄文件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot項目中使用Netty實現(xiàn)遠(yuǎn)程調(diào)用的示例代碼
眾所周知在進(jìn)行網(wǎng)絡(luò)連接的時候,建立套接字連接是一個非常消耗性能的事情,特別是在分布式的情況下,那么該通過什么技術(shù)去解決上述的問題呢,本文小編給大家介紹了SpringBoot項目中使用Netty實現(xiàn)遠(yuǎn)程調(diào)用的方法,需要的朋友可以參考下2025-04-04
Java的MyBatis框架中對數(shù)據(jù)庫進(jìn)行動態(tài)SQL查詢的教程
這篇文章主要介紹了Java的MyBatis框架中對數(shù)據(jù)庫進(jìn)行動態(tài)SQL查詢的教程,講解了MyBatis中一些控制查詢流程的常用語句,需要的朋友可以參考下2016-04-04
Java基于ArrayList實現(xiàn)群主發(fā)紅包功能
這篇文章主要介紹了Java基于ArrayList實現(xiàn)群主發(fā)紅包功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09
spring中bean id相同引發(fā)故障的分析與解決
最近在工作中遇到了關(guān)于bean id相同引發(fā)故障的問題,通過查找相關(guān)資料終于解決了,下面這篇文章主要給大家介紹了因為spring中bean id相同引發(fā)故障的分析與解決方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09

