java.io.IOException:不支持标记/重置

新手上路,请多包涵
try {
    //String location = dir1.getCanonicalPath()+"\\app_yamb_test1\\mySound.au";
    //displayMessage(location);
    AudioInputStream audio2 = AudioSystem.getAudioInputStream(getClass().getResourceAsStream("mySound.au"));
    Clip clip2 = AudioSystem.getClip();
    clip2.open(audio2);
    clip2.start();
} catch (UnsupportedAudioFileException uae) {
    System.out.println(uae);
    JOptionPane.showMessageDialog(null, uae.toString());
} catch (IOException ioe) {
    System.out.println("Couldn't find it");
    JOptionPane.showMessageDialog(null, ioe.toString());
} catch (LineUnavailableException lua) {
    System.out.println(lua);
    JOptionPane.showMessageDialog(null, lua.toString());
}

当我从 netbeans 运行应用程序时,这段代码工作正常。声音响起,无一例外。但是,当我从 dist 文件夹运行它时,声音不播放并且我在消息对话框中得到 java.io.IOException: mark/reset not supported

我怎样才能解决这个问题?

原文由 Crais 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 772
2 个回答

AudioSystem.getAudioInputStream(InputStream) 的文档说:

此方法的实现可能需要多个解析器来检查流以确定它们是否支持它。这些解析器必须能够标记流,读取足够的数据以确定它们是否支持该流,如果不支持,则将流的读取指针重置为其原始位置。如果输入流不支持这些操作,此方法可能会失败并抛出 IOException。

因此,您提供给此方法的流必须支持可选的 标记/重置 功能。用 BufferedInputStream 装饰你的资源流。

 //read audio data from whatever source (file/classloader/etc.)
InputStream audioSrc = getClass().getResourceAsStream("mySound.au");
//add buffer for mark/reset support
InputStream bufferedIn = new BufferedInputStream(audioSrc);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(bufferedIn);

原文由 McDowell 发布,翻译遵循 CC BY-SA 3.0 许可协议

在挣扎了一段时间并多次引用此页面后,我偶然发现了 这个 帮助我解决了问题。我最初能够加载一个 wav 文件,但随后只能播放一次,因为由于“不支持标记/重置”错误而无法倒带。真让人抓狂。

链接的代码从文件中读取 AudioInputStream,然后将 AudioInputStream 放入 BufferedInputStream,然后将 放回 AudioInputStream,如下所示:

 audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
BufferedInputStream bufferedInputStream = new BufferedInputStream(audioInputStream);
audioInputStream = new AudioInputStream(bufferedInputStream, audioInputStream.getFormat(), audioInputStream.getFrameLength());

最后它将读取的数据转换为 PCM 编码:

 audioInputStream = convertToPCM(audioInputStream);

convertToPCM 定义为:

 private static AudioInputStream convertToPCM(AudioInputStream audioInputStream)
    {
        AudioFormat m_format = audioInputStream.getFormat();

        if ((m_format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) &&
            (m_format.getEncoding() != AudioFormat.Encoding.PCM_UNSIGNED))
        {
            AudioFormat targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                m_format.getSampleRate(), 16,
                m_format.getChannels(), m_format.getChannels() * 2,
                m_format.getSampleRate(), m_format.isBigEndian());
            audioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);
    }

    return audioInputStream;
}

我相信他们这样做是因为 BufferedInputStream 比 audioInputStream 更好地处理标记/重置。希望这可以帮助那里的人。

原文由 AndyG 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题