开发者

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

目录
  • 1. 前言
  • 2. 读取Resource文件的五种常见方式
    • 2.1 使用 ClassPathResource(推荐)
    • 2.2 使用 ResourceLoader
    • 2.3 使用 @Value 注解
    • 2.4 使用 ResourceUtils
    • 2.5 通过 getResourceAsStream
    • 补充:读取Properties文件
  • 3. 完整实战案例:读取CSV文件并处理
    • 3.1 创建测试文件
    • 3.2 创建CSV处理器
    • 3.3 创建Controller测试
  • 4. 常见问题解决方案
    • 问题1:文件路径错误
    • 问题2:打包后文件读取失败
    • 问题3:读取Resource目录文件中文乱码
  • 5. 总结

    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 提供了 ClassPathResourandroidce,可直接从类路径获取资源

    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 readWXTCMysithResourceUtils(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(resourwww.devze.comce.getInputStream(), StandardCharsets.UTF_8);
    

    5. 总结

    Spring Boot提供了多种灵活的方式来读取resource目录下的文件。根据不同场景选用最合适的方式:

    • 如果需要 Spring 统一管理,推荐 ResourceLoader
    • 若只是简单注入小文件,可选 @Value;
    • 如果需要操作 File,可用 ResourceUtils。

    以上就是SpringBoot读取Resource目录文件的五种常见方式的详细内容,更多关于SpringBoot读取Resource目录文件的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜