获取 java.io.IOException: 每当我关闭程序时就关闭

问题描述 投票:0回答:1

每次我运行程序时它都运行良好。但是,当我运行程序几秒钟后关闭它时,我收到 java.io.IOException:已关闭错误。我尝试环顾四周,但找不到解决方案。我能找到的唯一解决方法是不在 try-catch 块中使用 e.printstacktrace,但这显然不能解决问题。这是代码:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Main extends Canvas implements Runnable
{
    private static final long serialVersionUID = -661485289446387445L;
    private Thread thread;
    public int blackPos;
    public int whitePos;
    public boolean isWhiteTurn; // In single player this determines board orientation, in multiplayer it doesn't
    public boolean running;
    public final int HEIGHT = 800;
    public final int WIDTH = 1200;
    //public File[] imgSrc = {new File("/images/urBoard.png"), new File("/rsc/urBackground.jpg")};
    public BufferedImage[] img = new BufferedImage[2];
    public Board board;

    public Main()
    {
        new Window(WIDTH, HEIGHT, this);
        board = new Board(this);
    }

    public void run()
    {
        requestFocus();
        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0D;
        double ns = 1.0E9D / amountOfTicks;
        double delta = 0.0D;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while (this.running)
        {
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while (delta >= 1.0D)
            {
                tick();
                delta -= 1.0D;
            }
            if (this.running) {
                render();
            }
            frames++;
            if (System.currentTimeMillis() - timer > 1000L)
            {
                timer += 1000L;
                System.out.println("FPS: " + frames);
                frames = frames;
                frames = 0;
            }
        }
    }

    public synchronized void start()
    {
        thread = new Thread(this);
        thread.start();
        running = true;
    }

    public synchronized void stop()
    {
        try
        {
            this.thread.join();
            this.running = false;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void tick()
    {
        board.tick();
    }

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

        try
        {
            img[0] = ImageIO.read(getClass().getResource("/rsc/urBoard.png"));
            img[1] = ImageIO.read(getClass().getResource("/rsc/urBackground.jpg"));
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        Graphics g = bs.getDrawGraphics();

        g.drawImage(img[1], 0, 0, WIDTH, HEIGHT, null);
        g.setColor(Color.GREEN);
        g.drawLine(200, 0, 200, 800);
        g.setFont(new Font("times new roman", Font.BOLD, 30));
        g.drawString("END PIECES", 10, 30);

        board.render(g);

        g.dispose();
        bs.show();
    }

    public static void main(String[] args)
    {
        new Main();
    }

}

这是每当我在运行几秒钟后关闭 GUI 时收到的错误:

java.io.IOException: closed
    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 main.Main.render(Main.java:99)
    at main.Main.run(Main.java:54)
    at java.lang.Thread.run(Thread.java:745)

我注意到,如果我在启动程序后立即关闭窗口,则不会出现错误。仅当我运行该程序大约 3-4 秒,然后关闭窗口时,才会出现这种情况。什么会导致这种情况发生,解决方法是什么?

java java-io ioexception javax.imageio
1个回答
1
投票

看起来您的

render()
方法可能在关闭应用程序时正在运行。由于您的资源在
render()
调用之间没有发生变化,因此将此块移动到
Main()
构造函数的开头,以便
img[]
设置一次,并在找不到资源时引发异常:

try {
    img[0] = ImageIO.read(getClass().getResource("/rsc/urBoard.png"));
    img[1] = ImageIO.read(getClass().getResource("/rsc/urBackground.jpg"));
} catch (IOException e) {
    throw new RuntimeException("Could not find resources");
}

字段

running
在不同的线程中使用,因此应将其标记为
volatile
,以便每个线程读取一致的值:

public volatile boolean running; 
© www.soinside.com 2019 - 2024. All rights reserved.