SpringBoot 2.0.1.RELEASE MVC应用读取resources目录文件的技术问询
解决SpringBoot中读取resources目录下文件夹内文件的问题
你在SpringBoot 2.0.1.RELEASE的MVC应用里,想要读取resources/elcordelaciutat文件夹下的所有.txt文件,目前写了一段代码但还没完成,我来帮你完善并优化这段逻辑,同时避开一些常见的坑。
首先,先给你一个完整的、健壮的控制器方法实现:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; @RestController public class FileReadingController { @GetMapping("/read-txt-files") public List<String> readTxtFiles() throws URISyntaxException, IOException { // 获取类加载器 ClassLoader classLoader = this.getClass().getClassLoader(); // 定位到目标文件夹 URL resourceUrl = classLoader.getResource("elcordelaciutat"); // 先校验文件夹是否存在,避免空指针 if (resourceUrl == null) { throw new RuntimeException("resources目录下未找到elcordelaciutat文件夹"); } Path configFilePath = Paths.get(resourceUrl.toURI()); // 遍历并筛选txt文件,提取文件名 List<String> cintaFileNames = Files.walk(configFilePath) .filter(Files::isRegularFile) // 先过滤出实际文件,排除子目录 .filter(filePath -> filePath.toString().endsWith(".txt")) // 这里替换了你原来的硬编码subpath,直接拿文件名更可靠 .map(filePath -> filePath.getFileName().toString().toUpperCase()) .collect(Collectors.toList()); return cintaFileNames; } }
几个关键优化点:
- 增加空校验:先判断
resourceUrl是否为null,避免文件夹不存在时抛出莫名其妙的空指针异常,报错信息也更清晰。 - 过滤文件类型:添加
Files::isRegularFile确保只处理文件,不会把文件夹当成文件来处理。 - 优化文件名提取:你原来用的
subpath(8,9)是硬编码路径索引,这很容易因为部署环境、路径结构变化失效,改用filePath.getFileName()直接获取文件名,逻辑更稳定。
注意:打包成Jar后的特殊处理
如果你的应用最终要打包成Jar包运行,上面的Files.walk可能会失效——因为Jar是压缩包,内部的资源不能直接用文件系统路径访问。这种情况下,建议用Spring自带的资源加载工具来处理:
import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.ArrayList; import java.util.List; @RestController public class JarCompatibleFileController { @GetMapping("/read-txt-from-jar") public List<String> readTxtFilesFromJar() throws IOException { // Spring提供的资源解析器,适配Jar环境 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); // 用通配符匹配目标文件夹下所有层级的txt文件 Resource[] resources = resolver.getResources("classpath:elcordelaciutat/**/*.txt"); List<String> cintaFileNames = new ArrayList<>(); for (Resource resource : resources) { String fileName = resource.getFilename(); if (fileName != null) { cintaFileNames.add(fileName.toUpperCase()); } } return cintaFileNames; } }
这个方案的好处是完全适配Jar包环境,而且用classpath:elcordelaciutat/**/*.txt通配符可以直接匹配所有子目录下的txt文件,不用手动遍历目录结构,代码更简洁。
内容的提问来源于stack exchange,提问作者en Peris
相关产品推荐
相关产品推荐

