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

如何从生成的exe文件中访问src/main/resources目录

解决Maven生成exe后无法读取src/main/resources文件的问题

兄弟,我之前开发桌面应用时也踩过这个一模一样的坑!问题核心出在你对资源文件的访问逻辑不对——当用Maven打包成exe(本质是把jar包封装进去)后,src/main/resources里的文件已经被打包到jar内部了,不再是磁盘上独立的文件目录。这时候用File类去访问肯定找不到,因为File只能操作磁盘上的实体文件,没法直接读取jar包里面的资源。

下面给你几种针对性的解决方案,按需选用:

1. 读取单个资源文件(最常见场景)

放弃用File,改用类加载器的getResourceAsStream()方法直接获取输入流,不管是开发环境(磁盘文件)还是打包后(jar内资源)都能正常读取:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// 注意路径:直接写resources下的文件名,不用加src/main/resources前缀
InputStream inputStream = classLoader.getResourceAsStream("config.properties");
// 用流读取内容,比如用BufferedReader处理文本文件
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
    String line;
    while ((line = reader.readLine()) != null) {
        // 处理文件内容逻辑
    }
} catch (IOException e) {
    e.printStackTrace();
}

2. 遍历resources目录下的所有文件

如果需要批量读取整个目录的文件,就不能用File[]了,因为jar里的目录不是真实磁盘目录。这里给你两种可行的处理方式:

方式一:提前生成文件清单(简单易维护)

在src/main/resources里放一个配置文件(比如resource-files.list),把需要加载的文件名逐行列进去,打包时这个清单会被一起打进jar。运行时先读取清单,再逐个加载资源:

// 先读取清单文件
InputStream listStream = classLoader.getResourceAsStream("resource-files.list");
try (BufferedReader listReader = new BufferedReader(new InputStreamReader(listStream))) {
    String fileName;
    while ((fileName = listReader.readLine()) != null) {
        // 加载每个文件
        InputStream fileStream = classLoader.getResourceAsStream(fileName);
        // 处理文件内容
    }
} catch (IOException e) {
    e.printStackTrace();
}

方式二:直接遍历jar包内的资源(适合动态场景)

如果需要动态遍历目录,得处理jar协议的URL,直接读取jar包内的条目,同时兼容开发环境的磁盘目录:

URL resourceDirUrl = classLoader.getResource("data-files");
if (resourceDirUrl == null) {
    System.err.println("目标资源目录不存在");
    return;
}

// 判断是开发环境(磁盘目录)还是打包后的jar环境
if (resourceDirUrl.getProtocol().equals("file")) {
    // 开发环境:直接用File遍历
    File dir = new File(resourceDirUrl.toURI());
    File[] files = dir.listFiles();
    if (files != null) {
        for (File file : files) {
            // 处理磁盘文件逻辑
        }
    }
} else if (resourceDirUrl.getProtocol().equals("jar")) {
    // 打包后:遍历jar内的条目
    try {
        JarURLConnection jarConn = (JarURLConnection) resourceDirUrl.openConnection();
        JarFile jarFile = jarConn.getJarFile();
        Enumeration<JarEntry> entries = jarFile.entries();
        String targetDirPrefix = "data-files/";
        
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            String entryName = entry.getName();
            // 过滤出目标目录下的文件,排除子目录
            if (entryName.startsWith(targetDirPrefix) && !entry.isDirectory()) {
                InputStream fileStream = classLoader.getResourceAsStream(entryName);
                // 处理jar内资源逻辑
            }
        }
        jarFile.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3. 确保Maven正确打包资源

最后别忘了检查你的pom.xml,确保src/main/resources下的文件都被正确打包到jar里,避免资源遗漏:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <!-- 包含所有文件和子目录 -->
                <include>**/*</include>
            </includes>
        </resource>
    </resources>
    <!-- 你的exe生成插件配置,比如launch4j相关配置 -->
</build>

核心思路就是:打包后资源不再是磁盘文件,必须用类加载器的流方式访问,根据你的具体场景选对应的方案就行,我当时用第一种方式就解决了大部分问题!

内容的提问来源于stack exchange,提问作者DarthDeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:40:21