Swing游戏开发:仅.mp3文件抛出FileNotFoundException问题求助
问题解决:类路径音频资源读取失败
核心问题分析
- 图像读取用
Main.class.getResource()正确加载了类路径下的资源,但音频用File(audioPath)是直接访问系统根目录的/audio文件夹,而非项目类路径里的audio目录,这才是file.exists()返回false的根本原因。 - 额外注意:
javax.sound.sampled.AudioSystem原生不支持MP3格式,哪怕路径正确也会报错,这也是你换WAV仍未解决的潜在卡点(先搞定路径,再处理格式问题)。
修复步骤
1. 用类路径方式读取音频资源(替代File)
不要用File访问类路径内的资源,直接通过getResourceAsStream()获取输入流,这是类路径资源的标准读取方式,不管是开发环境还是打包成Jar都能正常工作:
try { // 从类路径获取音频输入流 AudioInputStream audioInput = AudioSystem.getAudioInputStream( Objects.requireNonNull(Main.class.getResourceAsStream(audioPath)) ); Clip clip = AudioSystem.getClip(); clip.open(audioInput); clip.start(); clip.loop(Clip.LOOP_CONTINUOUSLY); } catch (Exception e) { System.out.println("音频读取失败"); throw new RuntimeException(e); }
2. 处理MP3格式支持问题
javax.sound.sampled仅原生支持WAV、AU等格式,要读取MP3需引入第三方库,比如JavaZoom的JLayer:
- 若用Maven,在pom.xml添加依赖:
<dependency> <groupId>javazoom</groupId> <artifactId>jlayer</artifactId> <version>1.0.1</version> </dependency>
- 用JLayer读取MP3的示例代码:
import javazoom.jl.player.Player; // ... try { Player player = new Player( Objects.requireNonNull(Main.class.getResourceAsStream(audioPath)) ); // 开线程播放,避免阻塞主线程 new Thread(() -> { try { player.play(); } catch (Exception e) { e.printStackTrace(); } }).start(); } catch (Exception e) { System.out.println("MP3读取失败"); throw new RuntimeException(e); }
3. 验证类路径资源有效性
确保audio和images文件夹在类路径根目录(比如IntelliJ中放在src/main/resources下,编译后会自动打包到类路径)。可通过打印资源URL确认:
System.out.println("音频资源URL: " + Main.class.getResource(audioPath));
如果输出null,说明资源不在类路径内,需调整文件夹位置。
完整修复后的代码示例
import javax.imageio.ImageIO; import javax.sound.sampled.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.util.Objects; public class Main { public static void main(String[] args) { String imagePath = "/images/Baker.png"; String audioPath = "/audio/QuestOfLegends.wav"; // 先测试WAV格式 // 验证资源是否存在 System.out.println("图像资源URL: " + Main.class.getResource(imagePath)); System.out.println("音频资源URL: " + Main.class.getResource(audioPath)); try { BufferedImage image = ImageIO.read(Objects.requireNonNull(Main.class.getResource(imagePath))); System.out.println("图像读取成功。"); } catch (IOException e) { System.out.println("图像读取失败。"); e.printStackTrace(); } try { InputStream audioStream = Objects.requireNonNull(Main.class.getResourceAsStream(audioPath)); AudioInputStream audioInput = AudioSystem.getAudioInputStream(audioStream); Clip clip = AudioSystem.getClip(); clip.open(audioInput); clip.start(); clip.loop(Clip.LOOP_CONTINUOUSLY); // 防止程序立即退出 Thread.sleep(Integer.MAX_VALUE); } catch (Exception e) { System.out.println("音频读取失败"); throw new RuntimeException(e); } } }
内容的提问来源于stack exchange,提问作者soybean
相关产品推荐
相关产品推荐

