开发必备!Spring Boot 项目中 resources 文件读取的 9 大方案详解
在 Spring Boot 项目中,resources
目录承载着大量的关键资源,如配置文件、模板文件、脚本资源、数据文件等。而如何以合适的方式高效、安全地读取这些资源,往往是开发者绕不过的关键环节。
不同的资源加载方式有不同的适用场景和底层机制,如果使用不当,不仅可能导致资源读取失败,还可能影响程序的可移植性和扩展性。
本文将为你系统性地讲解 Spring Boot 中读取 resources
文件的 9 种主流方式,并在最后附上一套完整的控制器 Demo 示例,集中展示这些方式在实际项目中的统一实现,帮助你在开发中快速定位最适合的资源加载方案。
资源读取的 9 大方式概览
我们先逐一列出每种方式的核心思路与适用场景。
1、ClassLoader.getResourceAsStream()
—— 通用类加载器读取方式
说明:以类加载器为起点,查找资源路径。
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("config/sample.txt");
-
不依赖 Spring,适用于任意 Java 项目;
-
路径从
classpath
根路径开始,不需要加/
。
2、Class.getResourceAsStream()
—— 相对于类路径加载资源
说明:当前类对象的路径定位方式,适合读取与类位于同一包下的资源。
InputStream inputStream = getClass().getResourceAsStream("/config/sample.txt");
-
以
/
开头则从根路径定位; -
相对路径时以类的包路径为基准。
3、使用 Spring 的 ResourceLoader
说明:借助 Spring 提供的通用资源加载抽象,可读取 classpath、file、http 等协议资源。
@Resourceprivate
ResourceLoader resourceLoader;
4、使用 ResourceUtils.getFile()
说明:用于将 classpath 路径资源转为 File
对象,适合需要文件路径的场景。
File file = ResourceUtils.getFile("classpath:config/sample.txt");
5、使用 ApplicationContext.getResource()
说明:通过上下文注入加载资源,与 ResourceLoader
类似。
@Resourceprivate
ApplicationContext context;
6、使用 ServletContext.getResourceAsStream()
说明:用于传统 Servlet 模型,从 Web 路径中获取资源文件。
@Resourceprivate
ServletContext servletContext;
7、使用 Java IO 的 File
说明:适用于读取项目中的真实文件,路径为实际操作系统路径。
File file = new File("src/main/resources/config/sample.txt");
8、使用 Java NIO 的 Paths
和 Files
说明:使用 Java 8 的现代化文件操作接口,线程安全且效率更高。
Path path = Paths.get("src/main/resources/config/sample.txt");
9、使用 Spring 的 ClassPathResource
说明:Spring 原生支持 classpath 路径加载,简单快捷。
ClassPathResource resource = new ClassPathResource("config/sample.txt");
统一完整代码实现示例
我们将在一个 Spring Boot 控制器中统一实现这 9 种方式,以
/resource/read/{method}
接口形式暴露,让你一目了然。
文件路径准备
请在 src/main/resources/config/sample.txt
文件中放置如下测试内容:
这是一个用于演示读取 resources 文件的示例文本。
控制器实现:com.icoderoad.resources.controller.ResourceReadController.java
package com.icoderoad.resources.controller;import jakarta.annotation.Resource;
import jakarta.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;import java.io.*;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Map;@RestController
@RequestMapping("/resource/read")
public class ResourceReadController {@Autowiredprivate ResourceLoader resourceLoader;@Autowiredprivate ApplicationContext applicationContext;@Autowiredprivate ServletContext servletContext;private final String filePath = "config/sample.txt";@GetMapping("/{method}")public Map<String, Object> readFile(@PathVariable String method) {Map<String, Object> result = new HashMap<>();try {String content = switch (method) {case "classloader" -> readByClassLoader();case "class" -> readByClass();case "loader" -> readByResourceLoader();case "utils" -> readByResourceUtils();case "context" -> readByApplicationContext();case "servlet" -> readByServletContext();case "file" -> readByFile();case "nio" -> readByNio();case "classpath" -> readByClassPathResource();default -> "Unsupported method!";};result.put("method", method);result.put("content", content);} catch (Exception e) {result.put("error", e.getMessage());}return result;}private String readByClassLoader() throws IOException {try (InputStream in = getClass().getClassLoader().getResourceAsStream(filePath)) {return streamToString(in);}}private String readByClass() throws IOException {try (InputStream in = getClass().getResourceAsStream("/" + filePath)) {return streamToString(in);}}private String readByResourceLoader() throws IOException {org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:" + filePath);try (InputStream in = resource.getInputStream()) {return streamToString(in);}}private String readByResourceUtils() throws IOException {File file = ResourceUtils.getFile("classpath:" + filePath);try (InputStream in = new FileInputStream(file)) {return streamToString(in);}}private String readByApplicationContext() throws IOException {org.springframework.core.io.Resource resource = applicationContext.getResource("classpath:" + filePath);try (InputStream in = resource.getInputStream()) {return streamToString(in);}}private String readByServletContext() throws IOException {// 仅适用于传统部署模式,如 war 包放入 Tomcat 时try (InputStream in = servletContext.getResourceAsStream("/WEB-INF/classes/" + filePath)) {return streamToString(in);}}private String readByFile() throws IOException {File file = new File("src/main/resources/" + filePath);try (InputStream in = new FileInputStream(file)) {return streamToString(in);}}private String readByNio() throws IOException {Path path = Paths.get("src/main/resources/" + filePath);try (InputStream in = Files.newInputStream(path)) {return streamToString(in);}}private String readByClassPathResource() throws IOException {ClassPathResource resource = new ClassPathResource(filePath);try (InputStream in = resource.getInputStream()) {return streamToString(in);}}private String streamToString(InputStream in) throws IOException {return new String(FileCopyUtils.copyToByteArray(in));}
}
使用方式说明
请求路径 | 对应加载方式 |
---|---|
/resource/read/classloader | ClassLoader.getResourceAsStream() |
/resource/read/class | Class.getResourceAsStream() |
/resource/read/loader | ResourceLoader |
/resource/read/utils | ResourceUtils.getFile() |
/resource/read/context | ApplicationContext.getResource() |
/resource/read/servlet | ServletContext.getResourceAsStream() |
/resource/read/file | new File() + FileInputStream |
/resource/read/nio | Paths + Files |
/resource/read/classpath | ClassPathResource |
总结
在本文中,我们不仅系统讲解了 Spring Boot 项目中读取 resources
目录下文件的 9 大方式,还构建了一个完整的统一控制器 Demo,集中展示它们在实际项目中的使用方式。你可以根据以下建议进行选择:
-
推荐方式(通用性 + 简洁性):
-
ClassLoader.getResourceAsStream()
-
ClassPathResource
-
ResourceLoader
-
-
特定场景方式(依赖文件路径、Web环境):
-
File
/Paths
/ServletContext
-
理解并熟练掌握这些方式,将极大提高你在 Spring Boot 项目中处理静态资源的灵活性与稳定性,特别是在构建插件机制、配置中心、文件服务等系统中。