You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java加载BufferedImage报javax.imageio.IIOException错误如何解决?

问题:加载BufferedImage时抛出javax.imageio.IIOException: Can't read input file!

编写TileDrawer类尝试加载SpriteSheet图片,但调用初始化方法时出现文件无法读取的错误,相关细节如下:

相关代码

TileDrawer.java

package mainGame;
        
//imports
                
public class TileDrawer {
        BufferedImage spriteSheet = null;    
                
         
        public void initSpriteSheet() {
                try {
                        this.spriteSheet = ImageIO.read(new File("resources\\spritesheet.png"));
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }        
        
        //irrelevant methods were here
}

GamePanel.java

package mainGame;

//imports

public class GamePanel extends JPanel implements Runnable {
        
        Thread gameThread;
        
        TileDrawer tileDrawer = new TileDrawer();

        //vars
        
        public GamePanel() {} //game panel
        
        public void startGameThread() {
                tileDrawer.initSpriteSheet(); // 调用位置                                                  
                gameThread = new Thread(this);
                gameThread.start();
        }
                 
        @Override
        public void run() {
                //stuff to make a functioning loop

                while (gameThread != null) {
                        
                        //more loop stuff

                        if (delta >= 1) { //delta is only used to cap the framerate

                                update();
                                repaint();
                                
                                //even more loop stuff
                        }
                }
        }

        public void update() {
                //update stuff here
        }

        protected void paintComponent(Graphics g) {

                super.paintComponent(g);

                Graphics2D g2 = (Graphics2D)g;

                //drawing stuff goes here

                g2.dispose();

        }
}

背景信息

  • 运行系统:Debian Linux
  • 项目目录结构:
MyGame
|------build
|      |------(Compiled java files)
|------src
|      |------Main.java (irrelevant)
|      |------GamePanel.java
|      |------TileDrawer.java
|      |------resources
|      |      |------spriteSheet.png
  • 编译运行命令:
cd /home/{my username}/MyGame/
javac -d ./build src/Main.java src/GamePanel.java src/TileDrawer.java
cd build
java mainGame.Main

已尝试但无效的方法

  • 将文件路径改为单斜杠
  • 将文件路径改为单斜杠并在开头加一个斜杠
  • 使用普通Image而非BufferedImage
  • 将图片文件放在与Java文件同一目录

解决方案

问题核心是运行时工作目录与资源位置不匹配、Linux路径分隔符差异,以及文件名大小写敏感三个问题叠加导致的,按以下步骤修复:

1. 复制资源文件到运行目录

编译时仅复制了Java类文件,src/resources目录并未同步到build目录,运行时程序找不到资源。修改编译命令,添加资源复制步骤:

cd /home/{my username}/MyGame/
javac -d ./build src/Main.java src/GamePanel.java src/TileDrawer.java
# 复制resources目录到build下
cp -r src/resources/ build/

2. 修正路径与文件名大小写

Linux系统用/作为路径分隔符,且严格区分文件名大小写。你的代码中写的是spritesheet.png,但实际文件是spriteSheet.png(S大写),修改TileDrawer中的路径代码:

public void initSpriteSheet() {
        try {
                this.spriteSheet = ImageIO.read(new File("resources/spriteSheet.png"));
        } catch (IOException e) {
                e.printStackTrace();
        }
}

3. 更可靠的资源读取方式(推荐)

如果后续要打包成JAR,用File读取会失效,建议改用类加载器读取资源流,无需依赖工作目录:

public void initSpriteSheet() {
        try {
                // 用类加载器读取根目录下的resources文件
                InputStream is = getClass().getResourceAsStream("/resources/spriteSheet.png");
                if (is == null) {
                        System.err.println("资源文件未找到!");
                        return;
                }
                this.spriteSheet = ImageIO.read(is);
                is.close();
        } catch (IOException e) {
                e.printStackTrace();
        }
}

内容的提问来源于stack exchange,提问作者Priff13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:25:18