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

编写Java外部类库时如何正确读取Jar包内的资源文件

问题根因

报java.nio.file.NoSuchFileException的核心原因是:项目A打包为JAR后,内部的txt文件不再是磁盘上独立存在的文件,而是被压缩在JAR归档包内部。你之前大概率用了File、Paths.get()这类面向磁盘文件系统的API读取,这类API无法识别JAR包内部的归档路径,自然找不到文件。
类路径下的资源(包括依赖JAR里的资源),必须用类加载器提供的资源流接口读取,不能用本地文件路径的读取逻辑。

实现步骤

1. 先确保资源被正确打进JAR

如果构建后txt根本没进JAR,什么读取方式都没用:

  • 最规范的做法是遵循Maven/Gradle的标准目录约定,把三个txt文件从src/main/java/packageTwo挪到src/main/resources/packageTwo目录下,构建工具会默认把resources目录下的所有文件按原结构打进JAR,最终JAR内的路径是/packageTwo/ImportantTextOne.txt,和A.class处于同个类路径层级。
  • 如果你坚持要把txt和Java源码放在同个src/main/java目录下,需要修改构建配置:比如Maven要在pom.xml的<build>标签下添加资源规则,指定编译时把src/main/java下的.txt文件一并纳入打包范围,否则构建时只会拷贝编译出来的.class文件,txt会被漏掉。

2. 正确的资源读取代码

在A.java中直接用当前类的getResourceAsStream方法读同包资源即可,这种方式不依赖磁盘路径,不管项目A是本地调试运行,还是作为JAR被其他项目引入,都能正常定位到资源:

package packageTwo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;

public class A {
    private void loadInternalResources() throws IOException {
        // 读取同包下的ImportantTextOne.txt
        // 路径不带开头的/时,是相对当前类所在包的相对路径,适配同包资源场景
        try (InputStream is = A.class.getResourceAsStream("ImportantTextOne.txt");
             BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
            String textContent = reader.lines().collect(Collectors.joining(System.lineSeparator()));
            // 这里写你的文本处理逻辑
        }

        // 另外两个文件用相同方式读取即可
        try (InputStream is2 = A.class.getResourceAsStream("ImportantTextTwo.txt")) {
            // 处理第二个文件内容
        }
        try (InputStream is3 = A.class.getResourceAsStream("ImportantTextThree.txt")) {
            // 处理第三个文件内容
        }
    }
}

路径写法说明

  • 用类名.class.getResourceAsStream()时,路径开头不加/代表相对当前类所在包查找资源,最适合你当前的场景
  • 如果路径开头加/,比如/packageTwo/ImportantTextOne.txt,就是从类路径根目录开始查找的绝对路径,两种写法都可正常运行,按需选择即可
  • 绝对不要写src/main/java/packageTwo/xxx.txt这类开发阶段的本地磁盘路径,打包后这个路径在运行环境中不存在

3. 常见避坑点

  • 不要先调用getResource()拿到URL再转成File或者Path对象读取:JAR内资源的URL是jar:file:/path/to/xxx.jar!/packageTwo/xxx.txt这种特殊的归档协议路径,文件系统API无法识别,还是会抛文件找不到的错误,直接拿流读就对了
  • 读取流时显式指定字符集(比如上面代码里的StandardCharsets.UTF_8),不要依赖系统默认字符集,避免跨环境运行时出现乱码
  • 用try-with-resources语法包裹流对象,自动关闭资源,避免内存泄漏
验证方法

重新构建项目A生成JAR后,直接用解压软件打开JAR包,确认三个txt文件和A.class都在packageTwo目录下,之后把这个JAR引入到任意外部项目调用,都不会再出现文件找不到的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:27:21