SpringBoot讀取Resource目錄文件的五種常見(jiàn)方式
1. 前言
在Spring Boot開(kāi)發(fā)中,我們經(jīng)常需要讀取src/main/resources目錄下的文件,src/main/resources 目錄下通常存放配置文件、模板、靜態(tài)資源、SQL腳本等,如何在運(yùn)行時(shí)讀取這些資源,是每個(gè)JAVA開(kāi)發(fā)者必須掌握的技能。
比如下面的Spring Boot項(xiàng)目中,資源文件的存儲(chǔ)位置:
src/
└── main/
└── resources/
├── static/ # 靜態(tài)資源
├── templates/ # 模板文件
├── config/ # 配置文件
└── data/ # 數(shù)據(jù)文件
本文博主將將從多種角度詳細(xì)介紹在 Spring Boot中讀取類(lèi)路徑(classpath)下資源的方法,并給出完整的代碼示例,相信小伙伴們看完一定能掌握這個(gè)技巧!
2. 讀取Resource文件的五種常見(jiàn)方式
2.1 使用 ClassPathResource(推薦)
Spring 提供了 ClassPathResource,可直接從類(lèi)路徑獲取資源
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);
}
}
}
測(cè)試示例:
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);
}
}
}
測(cè)試示例:
// 讀取 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)置的一個(gè)工具類(lèi), 可以將類(lèi)路徑資源轉(zhuǎn)換為 File 或 URL,適用于需要 java.io.File 操作的場(chǎng)景
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 通過(guò) getResourceAsStream
最原生的方式:通過(guò) 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);
}
}
}
補(bǔ)充:讀取Properties文件
有小伙伴說(shuō),讀取的配置文件是Properties文件,要如何來(lái)讀???下面博主做一個(gè)補(bǔ)充,依然使用 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. 完整實(shí)戰(zhàn)案例:讀取CSV文件并處理
下面我們通過(guò)一個(gè)實(shí)戰(zhàn)案例,來(lái)加深小伙伴的理解
3.1 創(chuàng)建測(cè)試文件
在 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()))) {
// 跳過(guò)標(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測(cè)試
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");
}
}
啟動(dòng)應(yīng)用后訪(fǎng)問(wèn):http://localhost:8080/users
輸出結(jié)果
看到輸出如下數(shù)據(jù)證明已經(jīng)讀取成功
[
{
"id": 1,
"name": "張三",
"email": "zhangsan@example.com"
},
{
"id": 2,
"name": "李四",
"email": "lisi@example.com"
}
]
4. 常見(jiàn)問(wèn)題解決方案
問(wèn)題1:文件路徑錯(cuò)誤
錯(cuò)誤信息:java.io.FileNotFoundException: class path resource [xxx] cannot be opened because it does not exist
解決方案:
檢查文件是否在src/main/resources目錄下
使用正確路徑(區(qū)分大小寫(xiě))
文件路徑前不要加/(正確:data/file.txt,錯(cuò)誤:/data/file.txt)
問(wèn)題2:打包后文件讀取失敗
錯(cuò)誤信息:FileNotFoundException when reading from JAR
解決方案:
使用ClassPathResource而不是File
避免使用new File(“classpath:…”)語(yǔ)法
使用getResourceAsStream()方法
問(wèn)題3:讀取Resource目錄文件中文亂碼
解決方案:
// 明確指定UTF-8編碼 new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8);
5. 總結(jié)
Spring Boot提供了多種靈活的方式來(lái)讀取resource目錄下的文件。根據(jù)不同場(chǎng)景選用最合適的方式:
- 如果需要
Spring統(tǒng)一管理,推薦ResourceLoader; - 若只是簡(jiǎn)單注入小文件,可選 @Value;
- 如果需要操作 File,可用 ResourceUtils。
以上就是SpringBoot讀取Resource目錄文件的五種常見(jiàn)方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot讀取Resource目錄文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
深入理解Java中觀(guān)察者模式與委托的對(duì)比
這篇文章主要介紹了Java中觀(guān)察者模式與委托的對(duì)比,觀(guān)察者模式:定義了一種一對(duì)多的依賴(lài)關(guān)系,讓多個(gè)觀(guān)察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象,委托的實(shí)現(xiàn)簡(jiǎn)單來(lái)講就是用反射來(lái)實(shí)現(xiàn)的,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
SpringBoot項(xiàng)目中使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例代碼
眾所周知在進(jìn)行網(wǎng)絡(luò)連接的時(shí)候,建立套接字連接是一個(gè)非常消耗性能的事情,特別是在分布式的情況下,那么該通過(guò)什么技術(shù)去解決上述的問(wèn)題呢,本文小編給大家介紹了SpringBoot項(xiàng)目中使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的方法,需要的朋友可以參考下2025-04-04
Java 中DateUtils日期工具類(lèi)的實(shí)例詳解
這篇文章主要介紹了Java 中DateUtils日期工具類(lèi)的實(shí)例詳解的相關(guān)資料,有時(shí)候開(kāi)發(fā)java項(xiàng)目使用日期類(lèi)型,這里介紹下日期工具類(lèi),需要的朋友可以參考下2017-08-08
Java的MyBatis框架中對(duì)數(shù)據(jù)庫(kù)進(jìn)行動(dòng)態(tài)SQL查詢(xún)的教程
這篇文章主要介紹了Java的MyBatis框架中對(duì)數(shù)據(jù)庫(kù)進(jìn)行動(dòng)態(tài)SQL查詢(xún)的教程,講解了MyBatis中一些控制查詢(xún)流程的常用語(yǔ)句,需要的朋友可以參考下2016-04-04
Java基于ArrayList實(shí)現(xiàn)群主發(fā)紅包功能
這篇文章主要介紹了Java基于ArrayList實(shí)現(xiàn)群主發(fā)紅包功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
spring中bean id相同引發(fā)故障的分析與解決
最近在工作中遇到了關(guān)于bean id相同引發(fā)故障的問(wèn)題,通過(guò)查找相關(guān)資料終于解決了,下面這篇文章主要給大家介紹了因?yàn)閟pring中bean id相同引發(fā)故障的分析與解決方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-09-09

