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

Ala*_*lan 4 java jar classloader

我有一个可运行的jar文件,它无法访问位于默认src目录之外的资源.根据我的理解,Class.getResource()和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());
    }
}
Run Code Online (Sandbox Code Playgroud)

文件夹设置:

root/
    src/
        foo/
            bar/
    res/
        img/
            img1.png
        audio/
            audio1.wav
Run Code Online (Sandbox Code Playgroud)

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

在生成jar文件方面有什么我缺少的吗?解压缩jar文件时,似乎所有内容都与img和audio目录在根目录中一致(给定上面的初始文件夹设置):

foo/
    /bar
img/
    img1.png
audio/
    audio1.wav
Run Code Online (Sandbox Code Playgroud)

Tob*_*ias 8

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

试试这个:

System.out.println(CLASS_LOADER.getResource(relativePath));
Run Code Online (Sandbox Code Playgroud)

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

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