由ImageIO

时间:2015-12-31 14:18:47

标签: java inputstream ioexception javax.imageio

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

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

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的实例。

但是当我试图加载Image时,它抛出异常。从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

1 个答案:

答案 0 :(得分:0)

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

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

希望这有帮助。

此致

Slava Imeshev