如何使用相同的String在IDE和.jar中加载资源

时间:2014-03-29 19:03:26

标签: java eclipse file jar classloader

我很担心java加载它的文件。

public static File loadFile(String file) throws IOException {
    URL url = ClassLoader.getSystemClassLoader().getResource(file);
    if(url == null){
        throw new IOException("Cannot find: " + file);
    }
    File ret;
    try {
        ret = new File(url.toURI());
        return ret;
    } catch (URISyntaxException e) {
        System.err.println("URISyntaxException in Utility.loadFile(): Tried to load: "+ file);
        throw new IOException("Cannot load: " + file);
    }
}

以下是Eclipse中项目结构的(已编辑)图像,其中加载资源的工作正常......

project structure in eclipse

加载资源时,我会调用上面的方法:

char sep = File.seperatorChar;
File file = Utility.loadFile(sep + "res" + sep + "shader"
                                 + sep + "some_shader.glsl");

虽然 - 这里是.jar看起来像(也编辑过)

contents of the .jar

一旦我用java -jar prog.jar运行jar,我就得到:

java.io.IOException: Cannot find: \res\shader\some_shader.glsl

我不想对任何类使用任何“相对”路径,我总是希望从项目结构的根目录(来自... / src / ..)使用资源的“绝对”路径。或者来自...... .jar!/ ...)

2 个答案:

答案 0 :(得分:1)

如果您使用Java加载资源,您总是可以使用'/'作为分隔符。

尝试

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("res/shader/some_shader.glsl"); // no leading slash

使用资源位于JVM类路径(-cp-classpath)中使您的JAR变为shure。

修改 您必须使用url.openStream()来获取InputStream - 新文件()。您的资源不是文件,因为它在JAR中

答案 1 :(得分:0)

  

"然而,我对Java如何加载它的文件感到困惑。"

加载时,您始终希望通过File从类路径加载而不是File将查找文件系统中的资源,该资源可能在您的文件系统上运行,但是一旦部署在jar上,就不会在其他系统上运行,而且很可能甚至不是你的。

对于网址,您需要了解的是获取网址的不同方式。使用类加载器(getClass().getClassLoader().getResource())时,搜索将从根开始,因此该路径

"res/shader/some_shader.glsl"

会奏效。另一方面,当只使用getClass().getResource() 而没有类加载器时,搜索将从调用类及其包位置开始。这是在文件结构中遍历的额外/

"/res/shader/some_shader.glsl"

更新

我不知道你做错了什么,但我没有问题。你可以看到代码。我把它出口到罐子里。它适用于jar

中的Eclipse

package stackoverflow;

import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class TestImagWithEclipse {
    private static final String PATH = "/res/shader/stack_reverse.png";

    public static void main(String[] args) {
        URL url = TestImagWithEclipse.class.getResource(PATH);
        ImageIcon icon = new ImageIcon(url);
        JOptionPane.showMessageDialog(null, new JLabel(icon), "It works", JOptionPane.PLAIN_MESSAGE);
    }
}

enter image description here

enter image description here