java.io.IOException:不支持mark/reset

Cra*_*ais 64 java audio 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());
}
Run Code Online (Sandbox Code Playgroud)

当我从netbeans运行应用程序时,此代码工作正常.声音播放,没有例外.但是,当我从dist文件夹运行它时,声音不会播放,我java.io.IOException: mark/reset not supported在消息对话框中显示.

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

McD*_*ell 131

文档AudioSystem.getAudioInputStream(InputStream)说:

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

因此,您为此方法提供的流必须支持可选的标记/重置功能.用a来装饰你的资源流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);
Run Code Online (Sandbox Code Playgroud)

  • Ty,这很有效.我修改了这样的代码:`BufferedInputStream myStream = new BufferedInputStream(getClass().getResourceAsStream("mySound.au")); AudioInputStream audio2 = AudioSystem.getAudioInputStream(myStream);`现在它工作=)PS如果有人可以格式化这个评论它会很棒= / (3认同)
  • 不能赞成这一点.无法弄清楚为什么我的音频无法从文件中正确加载.由于我是从文件加载的,所以我更容易这样做:FileInputStream fs = new FileInputStream(filename); BufferedInputStream myStream = new BufferedInputStream(fs); AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(myStream); (3认同)

And*_*dyG 5

经过一段时间的挣扎并多次引用这个页面之后,我偶然发现了这个问题.我最初能够加载一个wav文件,但随后只能播放一次,因为由于"标记/重置不支持"错误而无法回放它.这令人抓狂.

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

audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
BufferedInputStream bufferedInputStream = new BufferedInputStream(audioInputStream);
audioInputStream = new AudioInputStream(bufferedInputStream, audioInputStream.getFormat(), audioInputStream.getFrameLength());
Run Code Online (Sandbox Code Playgroud)

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

audioInputStream = convertToPCM(audioInputStream);
Run Code Online (Sandbox Code Playgroud)

使用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;
}
Run Code Online (Sandbox Code Playgroud)

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


Phi*_*ner 5

刚刚从其他有同样问题的人那里看到这个问题并引用了它。看起来这个问题是在 Java 7 中出现的。

Oracle Bug 数据库,#7095006

InputStream当是方法的参数时执行的测试getAudioInputStream()正在触发错误。音频资源文件中是否存在标记/重置功能与是否加载和播放无关Clip。鉴于此,当 a或足够时,没有理由更喜欢 anInputStream作为参数。URLFile

如果我们替换 aURL作为参数,则不会执行这个不必要的测试。修改OP代码:

AudioInputStream ais = AudioSystem.getAudioInputStream(getClass().getResource(fileName));
Run Code Online (Sandbox Code Playgroud)

详细信息可以在 API 中以及两种表单的描述文本中查看。 AudioSystem.getAudioInputStream(InputStream)

AudioSystem.getAudioInputStream(URL)