SpringBoot讀取Resource目錄文件的五種常見方式
1. 前言
在Spring Boot開發(fā)中,我們經(jīng)常需要讀取src/main/resources
目錄下的文件,src/main/resources
目錄下通常存放配置文件、模板、靜態(tài)資源、SQL腳本等,如何在運(yùn)行時(shí)讀取這些資源,是每個(gè)JAVA開發(fā)者必須掌握的技能。
比如下面的Spring Boot項(xiàng)目中,資源文件的存儲(chǔ)位置:
src/ └── main/ └── resources/ ├── static/ # 靜態(tài)資源 ├── templates/ # 模板文件 ├── config/ # 配置文件 └── data/ # 數(shù)據(jù)文件
本文博主將將從多種角度詳細(xì)介紹在 Spring Boot
中讀取類路徑(classpath
)下資源的方法,并給出完整的代碼示例,相信小伙伴們看完一定能掌握這個(gè)技巧!
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); } } }
測(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è)工具類, 可以將類路徑資源轉(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 通過 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); } } }
補(bǔ)充:讀取Properties文件
有小伙伴說,讀取的配置文件是Properties
文件,要如何來讀?。肯旅娌┲髯鲆粋€(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文件并處理
下面我們通過一個(gè)實(shí)戰(zhàn)案例,來加深小伙伴的理解
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()))) { // 跳過標(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)用后訪問: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:文件路徑錯(cuò)誤
錯(cuò)誤信息:java.io.FileNotFoundException: class path resource [xxx] cannot be opened because it does not exist
解決方案:
檢查文件是否在src/main/resources目錄下
使用正確路徑(區(qū)分大小寫)
文件路徑前不要加/(正確:data/file.txt,錯(cuò)誤:/data/file.txt)
問題2:打包后文件讀取失敗
錯(cuò)誤信息: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ù)不同場(chǎng)景選用最合適的方式:
- 如果需要
Spring
統(tǒng)一管理,推薦ResourceLoader
; - 若只是簡(jiǎn)單注入小文件,可選 @Value;
- 如果需要操作 File,可用 ResourceUtils。
以上就是SpringBoot讀取Resource目錄文件的五種常見方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot讀取Resource目錄文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot項(xiàng)目中使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的示例代碼
眾所周知在進(jìn)行網(wǎng)絡(luò)連接的時(shí)候,建立套接字連接是一個(gè)非常消耗性能的事情,特別是在分布式的情況下,那么該通過什么技術(shù)去解決上述的問題呢,本文小編給大家介紹了SpringBoot項(xiàng)目中使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用的方法,需要的朋友可以參考下2025-04-04Java 中DateUtils日期工具類的實(shí)例詳解
這篇文章主要介紹了Java 中DateUtils日期工具類的實(shí)例詳解的相關(guān)資料,有時(shí)候開發(fā)java項(xiàng)目使用日期類型,這里介紹下日期工具類,需要的朋友可以參考下2017-08-08Java的MyBatis框架中對(duì)數(shù)據(jù)庫進(jìn)行動(dòng)態(tài)SQL查詢的教程
這篇文章主要介紹了Java的MyBatis框架中對(duì)數(shù)據(jù)庫進(jìn)行動(dòng)態(tài)SQL查詢的教程,講解了MyBatis中一些控制查詢流程的常用語句,需要的朋友可以參考下2016-04-04Java基于ArrayList實(shí)現(xiàn)群主發(fā)紅包功能
這篇文章主要介紹了Java基于ArrayList實(shí)現(xiàn)群主發(fā)紅包功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09spring中bean id相同引發(fā)故障的分析與解決
最近在工作中遇到了關(guān)于bean id相同引發(fā)故障的問題,通過查找相關(guān)資料終于解決了,下面這篇文章主要給大家介紹了因?yàn)閟pring中bean id相同引發(fā)故障的分析與解決方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09