千家信息网

项目打包成jar后包无法读取src/main/resources下文件怎么解决

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要介绍"项目打包成jar后包无法读取src/main/resources下文件怎么解决",在日常操作中,相信很多人在项目打包成jar后包无法读取src/main/resources下文件怎么
千家信息网最后更新 2026年11月03日项目打包成jar后包无法读取src/main/resources下文件怎么解决

这篇文章主要介绍"项目打包成jar后包无法读取src/main/resources下文件怎么解决",在日常操作中,相信很多人在项目打包成jar后包无法读取src/main/resources下文件怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"项目打包成jar后包无法读取src/main/resources下文件怎么解决"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    一、项目场景

    在项目中读取文件时, 使用new File() 出现的一个坑以及解决流程
    这种问题不仅在本地文件读取时会遇到, 而且在下载项目下 (例如: src/main/resources目录下) 的文本时, 也会遇到,

    二、问题描述

    发现问题

    原来代码
    该代码功能是利用 common.io 包下的FileUtils来读取文件, 放到一个字符串中

    String s = FileUtils.readFileToString(new File("src/main/resources/holiday.txt"), "utf-8");

    这种路径书写方式 new File("src/main/resources/holiday.txt") , 在本地运行没问题,
    但是打包之后在服务器中运行出现了问题. 下面是错误截图

    可以看到在服务器中日志提示: java.io.FileNotFoundException: File 'holiday.txt' does not exist
    即: 在打包后, 一开始配置的路径src/main/resources下无法找到该文件

    分析问题

    项目在打包之后, 位于 resource目录下的文件, 最常见的就是各种Spring配置文件就会打包在 BOOT-INF/classes 目录下
    而FIle 在按照原来的文件路径src/main/resources/holiday.txt'去寻找, 必然找不到文件, 因此会报文件找不到的异常

    在定位问题的过程中发现, 这里 提供了一个思路
    就是SpringBoot中所有文件都在jar包中,没有一个实际的路径,因此可以使用以下方式

        /**     * 通过ClassPathResource类获取,建议SpringBoot中使用     * springboot项目中需要使用此种方法,因为jar包中没有一个实际的路径存放文件     *     * @param fileName     * @throws IOException     */    public void function6(String fileName) throws IOException {        ClassPathResource classPathResource = new ClassPathResource(fileName);        InputStream inputStream = classPathResource.getInputStream();        getFileContent(inputStream);    }

    为什么使用 ClassPathResource 后, 可以找到打包后的文件路径?

    上面代码的核心就是: 实例化ClassPathResource 对象. 然后调用getInputStream 来获取资源文件

    下面我们来分析这些代码
    在 ClassPathResource 在实例化时, 会初始化类加载器 classLoader 并将项目所用到的所有路径加载到类加载器 classLoader 中, 这些路径包括: java运行环境的jar, Maven 项目中的jar, 以及当前项目打包后的jar等(如下图)

    而 classPathResource.getInputStream 在获取资源文件时, 因为上面我们初始化了一个classLoader.
    所以classLoader不为空, 因此会执行 getResourceAsStream 方法, 我们来追一下这个方法

    getResourceAsStream 方法中的getResource是实际的业务处理方法, 我们继续深入

    getResource 方法如下图, 实际的功能就是递归调用自己, 去不断遍历 parent 下的路径, 获取对应的资源文件
    那么 parent 又是谁呢? 我们继续往下看

    看到这里我们豁然开朗, 这个神秘的 parent 就是类加载器classLoader!!!
    因此getResource 方法就是去不断遍历我们在ClassPathResource实例化时, 创建的类加载器下面的路径!!!(对应第1点)

    三、解决方案

    原来读取文件的代码如下

    String s = FileUtils.readFileToString(new File("src/main/resources/holiday.txt"), "utf-8");

    去查看 File 的构造函数, 看能否通过 InputStream 来构造
    从下图看是不行的

    方案一

    并且我们发现 org.apache.commons.io 下没有提供将 ClassPathResource 作为入参的读取文件的方法.
    因此我们必须手写读取文件的方法

    手写的代码如下
    主要注意 Resource resource = new ClassPathResource(fileName); is = resource.getInputStream();

        /**     * Java读取txt文件的内容     *     * @param fileName resources目录下文件名称(无需带目录)     * @return 将每行作为一个单位放到list中     */    public static List readTxtFile(String fileName) {        List listContent = new ArrayList<>();        InputStream is = null;        InputStreamReader isr = null;        BufferedReader br = null;        String encoding = "utf-8";        try {            Resource resource = new ClassPathResource(fileName);            is = resource.getInputStream();            isr = new InputStreamReader(is, encoding);            br = new BufferedReader(isr);            String lineTxt = null;            while ((lineTxt = br.readLine()) != null) {                listContent.add(lineTxt);            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                br.close();                isr.close();                is.close();            } catch (IOException e) {                e.printStackTrace();            }        }        return listContent;    }

    方案二

    这种方式对代码入侵较小, 核心还是利用 common.io 下的 FileUtils, 具体方法是
    利用FileUtils将ClassPathResource.getInputStream 得到的输入流复制到临时文件中, 然后读取这个临时文件
    这种方式缺点是: 需要创建临时文件, 如果待读取文件过大, 则重新创建文件和复制操作会消耗一定的空间和时间, 影响性能

      //方式二 利用FileUtils将ClassPathResource.getInputStream 得到的输入流复制到临时文件中  Resource resource = new ClassPathResource("holiday.txt");  InputStream inputStream = resource.getInputStream();  File tempFile = File.createTempFile("temp", ".txt");  FileUtils.copyInputStreamToFile(inputStream, tempFile);    String s = FileUtils.readFileToString(tempFile, StandardCharsets.UTF_8);

    意外出现

    到这里又出现了一个问题, 就是我用的测试项目因为在 maven 里面指定了某些格式的文件. 如下配置
    因为指定了banner.txt 以及 xml 与 properties结尾的文件作为资源被打包. 所以文件 holiday.txt 运行后还是访问不到
    有问题的pom.xml文件如下

                                                                                  src/main/java                                                                        **/*.xml                                                                                                                src/main/resources                                                                        **/*.xml                                        **/*.properties                                        **/banner.txt                                                                        

    打包后资源文件截图如下, 从该图中可以看到 holiday.txt 没有被打包进来

    程序运行之后的错误截图

    我们修改下指定打包的配置 **/*.txt
    这样配置后, 我们就可以将类路径下的所有txt 文件打包进行项目中了, 打包之后文件位置如下图
    或者我们可以去除项目中下面的代码配置, 这样做会默认打包 resources 下面的所有文件

                                                                               src/main/java                                                                        **/*.xml                                                                                                                src/main/resources                                                                        **/*.xml                                        **/*.properties                                        **/*.txt                                                                        

    修改pom文件后, 重新打包后资源文件(从这里可以看到 holiday.txt 被打包进来 )

    到此,关于"项目打包成jar后包无法读取src/main/resources下文件怎么解决"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

    文件 项目 方法 路径 问题 代码 就是 资源 配置 方式 目录 运行 实际 学习 实例 截图 方案 面的 utf-8 下图 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州淘业互联网络科技 山东特亿宝互联网科技有限公司 互联网科技工作委员会 高科技互联网 猪兼强互联网科技 亿策互联网科技 时间互联网络科技 深圳艾佳互联网科技 上海亿帐通互联网科技 滨湖区互联网智能科技产品供应 中国的互联网科技企业的崛起 互联网还是高科技吗 洛阳昕诺飞互联网科技有限公司 深圳市优智互联网科技有限公司 中国互联网十大科技股排名 爱医互联网络科技 上海京穆互联网科技有限公司 江苏互联网智能科技产品出厂价 云南互联网科技学费 北京军民互联网科技公司 科技金融是不是互联网金融 青岛互联网科技公司 安徽鑫晟辉互联网科技 多迪互联网科技有限公司 互联网公司会议桌创意科技软装饰 互联网金融中的现代科技 速维有品互联网信息科技(苏州)有限公司 企晟互联网信息科技有限公司 互联网科技实习生岗位 杭州融税互联网科技有限公司
    0