【问题标题】:InputStream closed by ImageIOImageIO 关闭的 InputStream
【发布时间】:2016-04-05 11:58:55
【问题描述】:

我在使用 ImageIO 时遇到了一个非常奇怪的问题。

我的 java 程序中的几个对象有一个 Image。我通过我的 ImageManager 使用静态方法 load 加载这些图像。

public static Image load(String path){
    Image img = null;
    try {
        img = ImageIO.read(ImageManager.class.getResource(path));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if(img == null){
        System.out.println("Image: '" + path + "' not found!");
    }

    return img;
}

每当我加载(静态)背景图像或在我的渲染方法中加载图像时都没有问题。

在我的 Card 类中将图像加载到静态变量时也没有问题。但是,一旦我从 Card 构造函数动态加载图像,就会抛出异常,说明流已关闭。

java.io.IOException: closed
Image: '/textures/cards/back.png' not found!
at javax.imageio.stream.ImageInputStreamImpl.checkClosed(ImageInputStreamImpl.java:110)
at javax.imageio.stream.ImageInputStreamImpl.close(ImageInputStreamImpl.java:857)
at javax.imageio.stream.FileCacheImageInputStream.close(FileCacheImageInputStream.java:250)
at javax.imageio.ImageIO.read(ImageIO.java:1451)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at visual.gfx.ImageManager.load(ImageManager.java:15)
at visual.Card.<init>(Card.java:49)
at visual.WorldController.render(WorldController.java:98)
at visual.WorldController.run(WorldController.java:116)
at java.lang.Thread.run(Thread.java:745)

所以要清楚: 这个:

public class Card{
    public static Image BACK = ImageManager.load("/textures/cards/back.png");
}

工作得很好。

还有这个:

public class Card{
    private Image image;

    public Card(){
        image = ImageManager.load("/textures/cards/back.png");
    }
}

导致 IOException。

谁能告诉我为什么会发生这种情况以及我该如何做不同的事情?

编辑:

我不确定这个异常是如何或为什么发生的,但我设法暂时修复了它。

我的程序结构是这样的:

public void run(){
    init();
        while(running){
            update();
            render();
        }
    finish();
}

我计划从 init 方法加载所有图像并创建所有实例。 但为了测试我的加载方法,我很快创建了一个Card 的实例。

但是当我尝试加载图像时,它引发了异常。从init() 方法加载图像解决了我的问题。

谁能告诉我为什么会有如此不同。

顺便说一句,这是我的渲染方法。

public void render(){
    BufferStrategy bs = getBufferStrategy();
    if(bs == null){
        createBufferStrategy(2);
        bs = getBufferStrategy();
    }

    Graphics g = bs.getDrawGraphics();
    g.drawImage(background, 0, 0, null);

    // render actual game

    game.render(g);

    // ------------------

    g.dispose();
    bs.show();
}
  • 我确实在项目中添加了一个 res 文件夹,以便图像位于:~/res/textures/cards/back.png

【问题讨论】:

  • Image: '/textures/cards/blue1.png' not found! ("/textures/cards/back.png"); blue1.png != back.png 请解释一下
  • 你的类路径中有/textures/cards/back.png吗?您不是在加载文件,而是在加载类路径资源。
  • @ControlAltDelete 这是我使用的两种纹理。我知道它们不一样,但会导致相同的错误
  • 是的,我确实在我的类路径中添加了一个 res 文件夹。图片位于:~/res/textures/cards/back.png
  • 您使用的是 Windows、Linux 还是其他?你的路径大小写正确吗?

标签: java inputstream ioexception javax.imageio


【解决方案1】:

ImageIO.read(URL) 的 Javadoc 有点模糊,但它似乎在内部根据 URL 缓存输入流,在多线程环境中它的行为并不明显。

如果我是你,我会尝试 ImageIO.read(InputStream)。

希望这会有所帮助。

问候,

斯拉瓦·伊梅舍夫

【讨论】:

  • ImageIO(实际上是ImageInputStream 实现)缓存any 输入流的内容,以便能够向后搜索,而不管输入如何。这种缓存是每个流(不是每个 URL)并且是完全线程安全的(从ImageIO.read(...) 的角度来看)。但是,按照您的建议使用 ImageIO.read(InputStream) 方法可能有助于找到异常的原因(很可能是资源不存在或不可读)。
猜你喜欢
  • 2023-04-06
  • 2018-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-23
  • 2017-02-25
  • 2016-08-20
  • 1970-01-01
相关资源
最近更新 更多