Spring Boot读取resources目录文件夹报错:URI is not hierarchical
解决resources目录文件夹读取时的URI非层级错误
问题原因
当项目打包成JAR包后,resources目录下的文件夹不再是文件系统中的真实目录,而是JAR包内的资源条目。此时用File类访问会报错java.lang.IllegalArgumentException: URI is not hierarchical——因为File只能操作文件系统中的实体,无法直接访问JAR包内的资源。你第二次尝试用getResourceAsStream()的返回值toString创建File也无效,因为getResourceAsStream()返回的是输入流对象,它的toString并非合法的文件路径。
解决方案
需要区分开发环境(文件系统目录)和打包后(JAR内资源)两种情况处理:
1. 通用处理代码
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URL; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class ResourceReader { public void readResourcesFolder(String folderPath) throws Exception { URL resourceUrl = getClass().getClassLoader().getResource(folderPath); if (resourceUrl == null) { throw new RuntimeException("指定的资源文件夹不存在: " + folderPath); } String protocol = resourceUrl.getProtocol(); if ("file".equals(protocol)) { // 开发环境:直接访问文件系统目录 File folder = new File(resourceUrl.toURI()); File[] fileList = folder.listFiles(); if (fileList != null) { for (File file : fileList) { if (file.isFile()) { System.out.println("找到文件: " + file.getName()); // 读取文件内容示例 try (InputStream is = new java.io.FileInputStream(file)) { // 此处处理文件内容 } } } } } else if ("jar".equals(protocol)) { // 打包后:访问JAR内的资源 String jarUri = resourceUrl.getPath(); // 解析JAR文件路径和内部文件夹路径 String jarPath = jarUri.substring(5, jarUri.indexOf("!")); String targetFolder = folderPath + "/"; JarFile jarFile = new JarFile(new URI(jarPath).getPath()); Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); // 筛选目标文件夹下的文件,排除文件夹本身 if (entry.getName().startsWith(targetFolder) && !entry.isDirectory()) { System.out.println("找到文件: " + entry.getName()); // 读取文件内容示例 try (InputStream is = jarFile.getInputStream(entry)) { // 此处处理文件内容 } } } jarFile.close(); } } // 测试调用 public static void main(String[] args) throws Exception { new ResourceReader().readResourcesFolder("jsonData"); } }
2. 注意事项
- 确保resources目录下的目标文件夹(如
jsonData)在打包时被正确包含(Maven/Gradle默认会包含resources下的所有文件和文件夹)。 - 读取文件内容时,优先使用输入流的方式,无论开发环境还是打包后都能兼容,避免依赖
File类。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

