它可以与File传递给的对象一起使用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"));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
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)
Run Code Online (Sandbox Code Playgroud)
@编辑
据答案@René Jeschke,@Phil Freihofner并且@Andrew Thompson,无论mark/reset被要求作为强制性protocal为Java Sound API与互动IO stream,恕我直言,类型buffered流,而不是raw一个应该被专门定义为参数的签名传递。这样做将使收窄到更理想的结果,而不是任意接受IO stream然后诉诸IOException为不利指标。
FileInputStream不支持标记/重置(用于随机访问),请将其包装为BufferedInputStream以获得标记/重置支持。
编辑:为什么会这样?getAudioFileFormat遍历当前注册的每个音频文件阅读器。每个阅读器都尝试通过读取某些特定字节来识别文件格式。因此,每个阅读器都必须撤消对流的更改(以允许其他阅读器在需要时重新读取所有数据)。
当您提供时File,这不是问题,因为每个阅读器只是打开一个新流,但是当您传递一个流时,每个阅读器必须标记当前流的位置,进行读取,并在完成后将流重置为其开始状态。
这就是为什么需要BufferedInputStream它的原因,因为它添加了一个内存中的缓冲区来支持标记/重置。
Edit2:因为问题是“为什么FileInputStream失败?” 我没有提出任何解决方法或替代方法,但试图解释为什么使用时失败FileInputStream。在某些情况下,您将无法使用URL或类似内容(例如,考虑到包含音频文件的二进制打包文件)。
| 归档时间: |
|
| 查看次数: |
1082 次 |
| 最近记录: |