【问题标题】:Loading resources (images) contained in a .Jar file or in the classpath加载包含在 .Jar 文件或类路径中的资源(图像)
【发布时间】:2014-03-05 16:15:44
【问题描述】:

所以我在堆栈交换上尝试了各种阅读各种修复这个问题的方法,大多数人说使用getResourceAsStream() 方法,我已经这样做了。 这是我的 Jar 资源输入法。

import java.io.InputStream;

    public class ResourceLoader {
        public static InputStream load(String path){
    InputStream input = ResourceLoader.class.getResourceAsStream(path);
    if(input == null){
        input = ResourceLoader.class.getResourceAsStream("/" + path);
    }
    return input;
    }
}

然后在我的ImageLoader 类中使用它。

public class ImageLoader {

public BufferedImage load(String path){
    try {
//          return ImageIO.read(getClass().getResource(path));
        return ImageIO.read(ResourceLoader.load(path));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
    }
}

图像被加载到主程序中使用

ImageLoader loader = new ImageLoader();
    spriteSheet = loader.load("/spritesheet.png");

现在在 Eclipse 中,游戏可以正常运行并加载所有图像。 但我想做的是将它导出到 Jar,我已经使用一些教程和 已成功使用包含我使用的图像的资源文件夹导出它。但是当我尝试运行 .jar 文件时,这个错误会在 cmd 行中弹出。

Exception in thread "Thread-2" java,lang.IllegalArgumentException: input == null
!
    at javax.imageio.ImageIO.read<Image.IO.java:1348>
    at gfx.ImageLoader.load<ImageLoader.java:15>
    at man.Gaim.init(Game.java:100>
    at main.Game.run<Game.java:150>
    at java.lang.Thread.run<Thread.java:722>

所以我收集的是图像文件位置没有被正确读取,或者我以某种方式输入错误,返回 null 并且没有图像加载。当 .Jar 运行时,Panel 出现,但没有绘制任何内容并给出错误。 该程序在 Eclipse 中运行良好,没有错误,所有图像都加载完毕。

编辑 1: Robermann 您的 getClass().getClassLoader().getResourceAsStream(path)) 解决方案有效。唯一的事情是我需要将图像文件放在带有 jar 的文件夹中。 例如我有 文件夹: ---文件.Jar ---图片.png ---图像文件夹 -------imagefolder.png中的更多图片

当它们位于这样的位置时,我可以加载所有图像。我的实际问题是,当我导出 .Jar 时,图像也位于内部,是否可以只使用位于 .jar 内部的图像?或者我是否必须像上面那样将 imgaes 打包在 jar 旁边的文件夹中,它可以工作,但我更多的是寻找一个可运行的 .Jar,我可以将它们转移到 tohers 而无需它们也需要 .jar 之外的图像。

【问题讨论】:

  • Load images in jar file 的可能重复项
  • 我尝试了这个,虽然我仍然得到同样的错误并且它在 eclipse 中不起作用。

标签: java jar


【解决方案1】:

如何加载类路径资源的问题反复出现,对于 Java 新手来说有点困惑:一些答案建议class.getClassLoader().getResourceAsStream,其他人建议class.getResourceAsStream,尽管它们的语义略有不同:

  1. class.getResourceAsStream 进行路径翻译
  2. class.getClassLoader().getResourceAsStream 不翻译路径

为了更好地展示差异,我将提出以下测试类,它以 4 种不同的方式尝试加载相同的资源(图像),根据使用的路径,只有 2 种工作。 Jar 内容树是:

班级:

package image;

import java.io.InputStream;

public class ImageLoader {
    public static void main(String[] args ){
        String cmd = null;
        InputStream is = null;
        final String image = "save.png";

        if("test1".equals(args[0])){
            cmd = "ImageLoader.class.getClassLoader().getResourceAsStream(\""+image+"\")";
            is = ImageLoader.class.getClassLoader().getResourceAsStream(image);     //YES, FOUND


        }else if("test2".equals(args[0])){
            cmd = "ImageLoader.class.getResourceAsStream(\""+image+"\")";
            is = ImageLoader.class.getResourceAsStream(image);                      //NOT FOUND

        }else if("test3".equals(args[0])){
            cmd = "ImageLoader.class.getResourceAsStream(\"/"+image+"\")";
            is = ImageLoader.class.getResourceAsStream("/"+image);                  //YES, FOUND

        }else if("test4".equals(args[0])){
            cmd = "ImageLoader.class.getClassLoader().getResourceAsStream(\"/"+image+"\")";
            is = ImageLoader.class.getClassLoader().getResourceAsStream("/"+image); //NOT FOUND

        }else {
            cmd = " ? ";
        }

        System.out.println("With "+cmd+", stream loaded: "+(is != null));
    }
}

运行:

java -cp resLoader.jar image.ImageLoader test4

希望这门课可以帮助理解不同的行为。

【讨论】:

  • 这就是.jar 现在的样子。图片位于根文件夹中,除非它们位于 res/PNG 之类的文件夹中,否则它们位于 .jar/PNG 中,否则它们位于根文件夹中。
  • 从类加载器传递,当然:java.awt.Image pic = javax.imageio.ImageIO.read(getClass().getClassLoader().getResourceAsStream("spritesheet.png")) - 见我在这里的回答:stackoverflow.com/questions/22045718/…
  • 所以我尝试了,虽然我仍然得到同样的错误。这就是我实现您的示例的方式,以防我做错了: return ImageIO.read(getClass().getClassLoader().getResourceAsStream(path));这取代了 return ImageIO.read(ResourceLoader.load(path));在 ImageLoader 类中。
  • 点击@jarrod 评论上的链接,或者给我们您现在使用的路径,以及 .jar 内容的树。
  • 这对我有很大帮助,结合解释,Eclipse 默认如何处理 Classpath(并将使用的资源文件夹添加到其中)
猜你喜欢
  • 2010-10-09
  • 2012-02-15
  • 2023-03-18
  • 2016-11-02
  • 2020-09-02
  • 1970-01-01
  • 2010-12-26
  • 2016-04-29
相关资源
最近更新 更多