0

我正在尝试播放 .wav 文件,但在使用相对路径函数时遇到了麻烦。

public class Main {

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

    public static void playSound() {
        try {
            File file = new File(Main.class.getResource("notification.wav").getFile());
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
            Clip clip = AudioSystem.getClip();
            clip.open(audioInputStream);
            clip.start();
        } catch(Exception ex) {
            System.out.println("Error playing sound.");
            ex.printStackTrace();
        }
    }
}

如果我在 IntelliJ 中运行上面的代码,我会收到错误:
java.io.FileNotFoundException: C:\Users\Dominik\Documents\IntelliJ%20Projects\nbbot\out\production\nbbot\com\company\notification.wav (The system cannot find the path specified)

如果我运行我构建的 .jar 应用程序,我会收到以下错误:
java.io.FileNotFoundException: file:\C:\Users\Dominik\Documents\IntelliJ%20Projects\nbbot\nbbot_jar\nbbot.jar!\com\company\notification.wav (The filename, directory name, or volume label syntax is incorrect) in Java?

.wav 文件是 Main 类,我在其中运行截取的代码位于同一文件夹中:
nbbot > src > com > company > Main.java; 通知.wav

这很奇怪,因为路径是正确的,只是读取文件应该没有问题。我也尝试过Main.class.getClass().getResource("notification.wav").getFile();.getPath()但也没有运气。如果我只是使用new File("notification.wav")并将 .wav 放在项目文件夹nbbot中,音频会作为意图播放,但只能在 IDE 中播放。

4

1 回答 1

1

你的计划被打破了。资源通常不是文件。调用.getFile()资源通常会导致代码损坏。例如,当你将你的应用程序打包到一个罐子里时,轰隆隆的响,打破了。一个java.io.File对象只能代表一个实际的文件。

几乎每个 API 还允许您传递 URL 或 InputStream 而不是文件,使用它们 - 这些是适用于所有资源的抽象。

getAudioInputStream就是这样一种方法,还好。它具有对 em 的覆盖。写这个:

try (AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(
  Main.class.getResource("notification.wav"))) {

  Clip clip = AudioSystem.getClip();
  clip.open(audioInputStream);
  clip.start();
}

这可能会解决这个问题,并且肯定意味着一旦您的文件被打包到一个 jar 中,您的代码将继续工作。

注意:InputStreams 是必须关闭的资源,因此,您需要使用 try-with-resources,否则您的应用程序最终会由于在播放足够多的音频后耗尽操作系统句柄而导致硬崩溃。

于 2022-01-12T15:22:33.440 回答