You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:55:17