getResourceAsStream返回null

问题

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

/src/initialization/Lifepaths.txt

用于加载文件的代码是:

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"
  • "初始化/ Lifepaths.txt"
  • "Lifepaths.txt"

这些都没有.I'vereadnumerousquestions这个主题,但它们都没有帮助 - 通常,他们只是说使用根路径加载文件,我已经在做了。那,或者只是从当前目录加载文件(只是loadfilename),我也试过了。该文件正在适当的位置编译到JAR中,并具有适当的名称。

我该如何解决这个问题?


#1 热门回答(109 赞)

Lifepaths.class.getClass().getResourceAsStream(...)使用系统类加载器加载资源,它显然失败,因为它没有看到你的JAR

Lifepaths.class.getResourceAsStream(...)使用加载Lifepaths类的相同类加载器加载资源,它应该可以访问JAR中的资源


#2 热门回答(43 赞)

规则如下:

  • 检查要在JAR中加载的文件的位置(从而确保它实际添加到JAR中)
  • 使用绝对路径:路径从JAR的根开始
  • 使用相对路径:path从你正在调用的类的包目录开始getResource / getResoucreAsStream

并尝试:

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

代替

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

(不确定它是否有所作为,但前者将使用正确的ClassLoader / JAR,而我不确定后者)


#3 热门回答(32 赞)

因此,有几种方法可以从jar获取资源,每种方法的语法略有不同,其中路径需要以不同方式指定。

我见过的最好的解释是这篇文章来自JavaWorld。我将在这里总结,但如果你想了解更多,你应该查看这篇文章。

方法

1)ClassLoader.getResourceAsStream()

格式:"/" - 分隔名称;没有前导"/"(所有名称都是绝对的)。

例如:this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");

2)Class.getResourceAsStream()

格式:"/" - 分隔名称;前导"/"表示绝对名称;所有其他名称都与该类的包相关

例如:this.getClass().getResourceAsStream("/some/pkg/resource.properties");