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

Kotlin执行Gradle distTar后无法读取src/main/resources文件

解决Jar包中读取resources目录下文件的问题

我太懂这种踩坑的感觉了——开发时能正常读取src/main/resources/user.json,但用Gradle的distTar打包成Jar后就抛出FileNotFoundException,核心原因是:Jar里的资源不是操作系统文件系统中的真实文件,而是嵌入在Jar内部的一个资源条目,file:/app/api-latest/lib/api-latest.jar!/user.json这种路径并不是一个真实的文件路径,File类根本无法解析它。

为什么你之前的方式都不行?

不管你怎么构造File对象,只要是用文件系统路径去访问Jar内的资源,必然会失败——因为File类只能操作操作系统文件系统中存在的实体文件,而Jar内的资源是被压缩在Jar包里的,不属于文件系统的一部分。

正确的访问方式(Kotlin实现)

下面几种方式不管是开发环境还是打包成Jar后都能正常工作:

1. 最推荐:用类加载器获取输入流直接读取

这是通用且安全的方式,直接从类路径加载资源的输入流:

fun readFileFromResources(filename: String): String {
    // 用当前类的类加载器获取资源输入流
    return this::class.java.classLoader.getResourceAsStream(filename)?.use { inputStream ->
        // use函数会自动关闭流,避免资源泄漏
        inputStream.bufferedReader().readText()
    } ?: throw IllegalArgumentException("找不到资源文件:$filename")
}

调用的时候直接传"user.json"就行,因为src/main/resources下的文件会被打包到Jar的类路径根目录。

2. 获取资源URL后打开流(适合需要URL的场景)

如果你需要获取资源的URL(比如某些API要求传入URL),可以用getResource,但绝对不能把URL转成File,而是要通过URL打开输入流:

fun readResourceByUrl(filename: String): String {
    val resourceUrl = this::class.java.classLoader.getResource(filename)
        ?: throw IllegalArgumentException("找不到资源文件:$filename")
    
    return resourceUrl.openStream().use { inputStream ->
        inputStream.bufferedReader().readText()
    }
}

3. Spring/Spring Boot项目专属:用框架工具类

如果你的项目是Spring或Spring Boot,可以直接用框架提供的ResourceUtils简化操作:

import org.springframework.util.ResourceUtils

fun readSpringResource(filename: String): String {
    val resourceUrl = ResourceUtils.getURL("classpath:$filename")
    return resourceUrl.openStream().use { inputStream ->
        inputStream.bufferedReader().readText()
    }
}

额外检查事项

  • 确认user.json确实在src/main/resources目录下,打包后可以用jar tf api-latest.jar命令查看Jar内容,确保根目录下有user.json;
  • 文件名注意大小写,类加载器查找资源时是严格区分大小写的;
  • 永远不要尝试将Jar内的资源路径转换成File对象,这是不可能成功的——Jar内的资源不是独立文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:07:43