SpringBoot读取Resource目录文件的五种常见方式

 更新时间:2025年07月16日 08:51:53   作者:Micro麦可乐  
在Spring Boot开发中,我们经常需要读取src/main/resources目录下的文件,src/main/resources 目录下通常存放配置文件、模板、静态资源、SQL脚本等,本文给大家介绍了SpringBoot读取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

ResourceUtilsSpring 内置的一个工具类, 可以将类路径资源转换为 FileURL,适用于需要 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

最原生的方式:通过 ClassClassLoadergetResourceAsStream

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。

以上就是SpringBoot读取Resource目录文件的五种常见方式的详细内容,更多关于SpringBoot读取Resource目录文件的资料请关注脚本之家其它相关文章!

相关文章

  • 简述Java图像倾斜方法及实例

    简述Java图像倾斜方法及实例

    这篇文章主要介绍了Java图像倾斜的方法及实例,需要的朋友可以参考下
    2017-09-09
  • 深入理解Java中观察者模式与委托的对比

    深入理解Java中观察者模式与委托的对比

    这篇文章主要介绍了Java中观察者模式与委托的对比,观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,委托的实现简单来讲就是用反射来实现的,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • SpringBoot项目中使用Netty实现远程调用的示例代码

    SpringBoot项目中使用Netty实现远程调用的示例代码

    众所周知在进行网络连接的时候,建立套接字连接是一个非常消耗性能的事情,特别是在分布式的情况下,那么该通过什么技术去解决上述的问题呢,本文小编给大家介绍了SpringBoot项目中使用Netty实现远程调用的方法,需要的朋友可以参考下
    2025-04-04
  • Java 中DateUtils日期工具类的实例详解

    Java 中DateUtils日期工具类的实例详解

    这篇文章主要介绍了Java 中DateUtils日期工具类的实例详解的相关资料,有时候开发java项目使用日期类型,这里介绍下日期工具类,需要的朋友可以参考下
    2017-08-08
  • Java的MyBatis框架中对数据库进行动态SQL查询的教程

    Java的MyBatis框架中对数据库进行动态SQL查询的教程

    这篇文章主要介绍了Java的MyBatis框架中对数据库进行动态SQL查询的教程,讲解了MyBatis中一些控制查询流程的常用语句,需要的朋友可以参考下
    2016-04-04
  • 通过JDK源码角度分析Long类详解

    通过JDK源码角度分析Long类详解

    这篇文章主要给大家介绍了关于通过JDK源码角度分析Long类的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用long类具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • jmeter基础逻辑控制器之if控制器的使用

    jmeter基础逻辑控制器之if控制器的使用

    在实际工作中,当使用JMeter做性能脚本或者接口脚本时,当遇到需要对不同的条件做不同的操作时,我们可以使用JMeter中if控制器来实现,本文就详细的介绍一下如何使用
    2021-11-11
  • Java超详细讲解排序二叉树

    Java超详细讲解排序二叉树

    排序二叉树的特点是一个父节点只能有左右两个子节点、左节点的值比父节点要小、右节点的值要比父节点要大,难度并不大,但是得花时间来理解
    2022-06-06
  • Java基于ArrayList实现群主发红包功能

    Java基于ArrayList实现群主发红包功能

    这篇文章主要介绍了Java基于ArrayList实现群主发红包功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • spring中bean id相同引发故障的分析与解决

    spring中bean id相同引发故障的分析与解决

    最近在工作中遇到了关于bean id相同引发故障的问题,通过查找相关资料终于解决了,下面这篇文章主要给大家介绍了因为spring中bean id相同引发故障的分析与解决方法,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09

最新评论