2015-12-31 2 views
3

У меня возникла очень странная проблема с ImageIO.InputStream закрыт ImageIO

Пара объектов в моей программе java имеет изображение. Я загружаю эти изображения через мой 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, вызывается Исключение, говорящее, что поток закрыт.

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.

Может кто-нибудь сказать мне, почему это происходит и как я могу поступать по-другому?

Edit:

Я не знаю, как и почему это исключение произошло, но я сумел временно исправить.

Структура моей программы было так:

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

Я планировал, чтобы загрузить все изображения и создавать все экземпляры из метода инициализации. Но просто для проверки моего метода загрузки я быстро создал экземпляр Card.

Но когда я попытался загрузить изображение, он выбрал исключение. Загрузка изображения из метода init() решила мою проблему.

Может ли кто-нибудь сказать мне, почему это имеет значение.

btw это мой метод визуализации.

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(); 
} 
  • Я сделал добавить рес папку для проекта, так что изображения расположены: ~/Рез/текстур/карт/back.png
+3

'Изображение: '/textures/cards/blue1.png' не найден' '("/textures/cards/back.png");' blue1.png! ! = back.png, пожалуйста, объясните – ControlAltDel

+0

Является ли '/ textures/cards/back.png' в вашем пути к классу? Вы не загружаете файлы, а ресурсы classpath. – malaguna

+0

@ControlAltDelete это две текстуры, которые я использую. Я знаю, что они не совпадают, но это приводит к той же ошибке –

ответ

0

Javadoc для ImageIO.read (URL) немного расплывчато, но, похоже, он кэширует входной поток внутренне на основе URL-адреса, и неясно, как он ведет себя в многопоточной среде.

Я бы сделал снимок в ImageIO.read (InputStream), если бы был вами.

Надеюсь, это поможет.

С уважением,

Slava Imeshev

+0

'ImageIO' (или, действительно, реализаций' ImageInputStream') кэширует содержимое * любого * входного потока, чтобы иметь возможность искать назад, независимо от ввода. Это кеширование * для потока * (не для каждого URL) и полностью потокобезопасно (с точки зрения «ImageIO.read (...)»). Однако использование метода 'ImageIO.read (InputStream)', как вы предлагаете, может помочь найти причину исключения (что, скорее всего, заключается в том, что ресурс не существует или не читается). – haraldK