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

4

我有一个可运行的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());
    }
}

文件夹设置:

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

当我尝试执行JAR可执行文件本身时,问题就出现了。但奇怪的是,我无法通过Eclipse IDE复制这个问题,因为Eclipse实际上可以正确解析路径。我已经通过(项目->属性->Java构建路径->添加文件夹)将资源目录添加到构建路径中,所以Java应该能够在运行时找到资源文件夹。
在生成JAR文件方面,我是否漏掉了什么?当解压缩JAR文件时,一切似乎都井然有序,img和audio目录位于根目录下(假定上述初始文件夹设置正确)。
foo/
    /bar
img/
    img1.png
audio/
    audio1.wav

你能发布“relativePath”值吗? - David Pérez Cabrera
1
一旦资源被打包成jar文件,它就不再是一个“文件”了。如果你把它的URI放到一个File中,文件将无法被找到,因为它不在文件系统中。你应该将其作为输入流来使用,而不是文件。 - RealSkeptic
@DavidPérezCabrera:例如:img/img1.png - Alan
1个回答

9

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

尝试这个:

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

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

通常,您只需要读取资源。在这种情况下,请使用getResourceAsStream()打开一个InputStream


1
简短、简洁、写作精良的解释 - andylamax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接