它适用于传递给File
的{{1}}个对象,但为什么它会因下面的AudioSystem#getAudioFileFormat
对象而失败?有什么建议吗?
InputStream
输出:
import java.io.*;
import javax.sound.sampled.*;
public class Test {
public static void main(String[] args) throws Exception {
AudioSystem.getAudioFileFormat(new File(
"myaudio.wav"));
AudioSystem.getAudioFileFormat(new FileInputStream(
"myaudio.wav"));
}
}
的 @EDIT 的
根据Exception in thread "main" java.io.IOException: mark/reset not supported
at java.io.InputStream.reset(InputStream.java:330)
at com.sun.media.sound.WaveFileReader.getAudioFileFormat(WaveFileReader.java:88)
at javax.sound.sampled.AudioSystem.getAudioFileFormat(AudioSystem.java:985)
at Test.main(Test.java:10)
,@René Jeschke
和@Phil Freihofner
的答案,只要@Andrew Thompson
作为mark/reset
与Java Sound API
互动的强制性协议, 1}},恕我直言,IO stream
流而不是buffered
流的类型应该特别定义为要传递的参数的签名。这样做会缩小到比任意接受raw
然后诉诸IO stream
作为不利指标更令人满意的结果。
答案 0 :(得分:5)
FileInputStream
不支持标记/重置(用于随机访问),将其包装到BufferedInputStream
以获得标记/重置支持。
编辑:为什么会这样? getAudioFileFormat
遍历当前注册的每个音频文件阅读器。每个读者都试图通过读取一些特定的字节来识别文件格式。因此,每个读者都必须撤消对流的更改(以允许其他读者在需要时重新读取所有数据)。
当您提供File
时,这不是问题,因为每个阅读器只是打开一个新流,但是当您传递流时,每个阅读器必须标记当前流位置,执行其读数并重置流它完成时的开始状态。
这就是你需要BufferedInputStream
的原因,因为它增加了一个内存缓冲区来支持标记/重置。
Edit2:因为问题是'为什么它会因FileInputStream而失败?'我没有建议任何变通方法或替换,但试图解释为什么当使用FileInputStream
时失败。在某些情况下,您无法使用URL等(例如,考虑包含音频文件的二进制包文件)。
答案 1 :(得分:1)
这适用于我(与其他Wavs合作)。
AudioSystem.getAudioFileFormat(new File(
"myaudio.wav").toURI().toURL());
JavaSound info. page上的代码也使用了网址。
如果你所拥有的东西既不是File
也不是URL
,那么问题就可以通过缓存来修复,如RenéJeschke所说,或者我通常只是阅读所有{{1}并建立一个byte[]
。 可定位(支持标记/重置)。
答案 2 :(得分:1)
AudioSystem.getAudioFileFormat()方法在包javax.sound.sampled.spi中调用抽象类“AudioFileReader”。
方法AudioFileFormat getAudioFileFormat(InputStream stream) throws UnsupportedAudioFileException, IOException;
的代码中的注释表示可能需要标记/重置:
* Obtains the audio file format of the input stream provided. The stream must * point to valid audio file data. In general, audio file readers may * need to read some data from the stream before determining whether they * support it. These parsers must * be able to mark the stream, read enough data to determine whether they * support the stream, and, if not, reset the stream's read pointer to its original * position. If the input stream does not support this, this method may fail * with an <code>IOException</code>.
相比之下,表单public abstract AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException;
和public abstract AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException;
不要提出这个要求。对解析器的支持仅提供InputStream作为参数。
AudioSystem.getAudioInputStream()也针对各种重载进行了类似的评论。
当在使用音频文件的情况下出现标记/重置错误时,首先尝试的解决方案是通过其URL加载文件,从而避免标记/重置要求(如Andrew Thompson所述)。如果这不起作用,请确保使用BufferedInputStream,但它不应该用于有效的音频文件。
此问题也在Oracle Bug数据库中记录为错误#7095006。