getResourceAsStream 返回 null

2022-08-31 05:45:30

我正在从我的Java项目的已编译JAR中的包中加载文本文件。相关目录结构如下:

/src/initialization/Lifepaths.txt

我的代码通过调用 Class::getResourceAsStream 来加载文件以返回 InputStream

public class Lifepaths {
    public static void execute() {
        System.out.println(Lifepaths.class.getClass().
            getResourceAsStream("/initialization/Lifepaths.txt"));
    }

    private Lifepaths() {}

    //This is temporary; will eventually be called from outside
    public static void main(String[] args) {execute();}
}

打印输出将始终打印,无论我使用什么。我不确定为什么上述方法不起作用,所以我也尝试过:null

  • "/src/initialization/Lifepaths.txt"
  • "initialization/Lifepaths.txt"
  • "Lifepaths.txt"

这些都不起作用。到目前为止,我已经阅读了有关该主题的许多问题,但没有一个有帮助 - 通常,它们只是说使用根路径加载文件,我已经在这样做了。那,或者只是从当前目录加载文件(只是加载),我也尝试过。该文件正在编译到 JAR 中具有适当名称的适当位置。filename

我该如何解决这个问题?


答案 1

Lifepaths.class.getClass().getResourceAsStream(...)使用系统类装入器加载资源,它显然会失败,因为它看不到您的 JAR

Lifepaths.class.getResourceAsStream(...)使用与加载 Lifepath 类相同的类装入器装入资源,并且它应该有权访问 JAR 中的资源


答案 2

规则如下:

  1. 检查要在 JAR 中加载的文件的位置(因此还要确保它实际添加到 JAR 中)
  2. 使用绝对路径:路径从 JAR 的根目录开始
  3. 使用相对路径:路径从你调用的类 getResource/getResoucreAsStream 的包目录开始

并尝试:

Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")

而不是

Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")

(不确定是否有区别,但前者将使用正确的ClassLoader/ JAR,而我不确定后者)