Java 类加载器无法在 jar 文件中找到资源

Java classloader not able to find resource in jar file

我有一个可运行的 jar 文件,它无法访问位于默认 src 目录之外的我的资源。根据我对 What is the difference between Class.getResource() and ClassLoader.getResource() 的理解,我应该能够使用以下 getResourceFile 函数访问 root/res/img/img1.png(请参阅下面的文件夹设置):

public class Foo {

    private static final ClassLoader CLASS_LOADER = Foo.class.getClassLoader();

    public static File getResourceFile(String relativePath) {
        // Since I'm using getClassLoader, the path will resolve starting from 
        // the root of the classpath and it'll take an absolute resource name
        // usage: getResourceFile("img/img1.png")
        // result: Exception in thread "main" java.lang.NullPointerException
        return new File(CLASS_LOADER.getResource(relativePath).getFile());
    }
}

文件夹设置:

root/
    src/
        foo/
            bar/
    res/
        img/
            img1.png
        audio/
            audio1.wav

当我尝试执行 jar 可执行文件本身时出现问题。然而,奇怪的是我无法通过实际上能够正确解析路径的eclipse IDE 来复制它。我已经通过(项目 -> 属性 -> Java 构建路径 -> 添加文件夹)将资源目录添加到构建路径,因此 Java 应该能够在运行时找到资源文件夹。

在生成 jar 文件方面我是否遗漏了什么?解压 jar 文件时,一切似乎都井井有条,img 和 audio 目录位于根目录中(鉴于上述初始文件夹设置):

foo/
    /bar
img/
    img1.png
audio/
    audio1.wav

Files 只能用于表示文件系统中的实际文件。一旦将文件打包到 JAR 中,资源 (img/img1.png) 就不再是文件,而是 JAR 文件中的一个条目。只要您使用 Eclipse 中的文件夹结构,资源就是单独的文件,所以一切都很好。

试试这个:

System.out.println(CLASS_LOADER.getResource(relativePath));

它将打印 URL,但它不是文件系统中文件的有效路径,而是 JAR 文件中条目的有效路径。

通常,您只想阅读资源。在这种情况下,使用 getResourceAsStream() 打开一个 InputStream.