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
相关产品推荐
相关产品推荐

