首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >未能将InputStream对象传递给Java

未能将InputStream对象传递给Java
EN

Stack Overflow用户
提问于 2012-04-02 08:50:27
回答 3查看 1.2K关注 0票数 4

它适用于传递给File对象的AudioSystem#getAudioFileFormat对象,但是为什么下面的InputStream对象会失败呢?有什么建议吗?

代码语言:javascript
运行
复制
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"));

    }
}

输出:

代码语言:javascript
运行
复制
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 APIIO stream、IMHO交互的强制协议,buffered流的类型(而不是raw流)应该是(特别是E 216)定义为要传递的参数的签名。这样做将缩小到比任意接受IO stream,然后求助于IOException作为不利指标更理想的结果。

EN

回答 3

Stack Overflow用户

发布于 2012-04-02 08:53:53

FileInputStream不支持标记/重置(用于随机访问),将其包装到BufferedInputStream中以获得标记/重置支持。

编辑:为什么会这样?getAudioFileFormat遍历当前注册的每个音频文件阅读器。每个阅读器都试图通过读取一些特定的字节来标识文件格式。因此,每个读取器都必须撤销对流的更改(如果需要,允许其他读取器重新读取所有数据)。

当您提供一个File时,这不是一个问题,因为每个读取器只是打开一个新的流,但是当您传递一个流时,每个阅读器必须标记当前流的位置,做它的读取,并在它完成时将流重置到它的起始状态。

这就是为什么您需要BufferedInputStream,因为它添加了一个内存中的缓冲区来支持标记/重置。

Edit2:因为问题是“为什么FileInputStream失败了?”我没有提出任何解决办法,也没有提出替代方案,但我试图解释为什么在使用FileInputStream时它会失败。在有些情况下,您不能使用URL等(例如,包含音频文件的二进制包文件)。

票数 5
EN

Stack Overflow用户

发布于 2012-04-02 09:04:02

这适用于我(与其他Wavs)。

代码语言:javascript
运行
复制
AudioSystem.getAudioFileFormat(new File(
            "myaudio.wav").toURI().toURL());

JavaSound info. page上的代码也使用一个URL。

如果你所拥有的不是FileURL,问题可以通过缓冲来解决,就像勒内·耶施克提到的那样,或者我通常只是阅读所有的byte[]并建立一个ByteArrayInputStream可定位的(支持标记/重置)。

票数 1
EN

Stack Overflow用户

发布于 2012-04-03 22:30:32

AudioSystem.getAudioFileFormat()方法调用包javax.sound.sampled.spi中的抽象类"AudioFileReader“。

方法AudioFileFormat getAudioFileFormat(InputStream stream) throws UnsupportedAudioFileException, IOException;的代码中的注释指出,可能需要标记/重置:

*获取所提供的输入流的音频文件格式。流必须*指向有效的音频文件数据。通常,音频文件读取器可能需要从流中读取一些数据,然后才能确定它们是否支持它。这些解析器必须*能够标记流,读取足够的数据以确定它们是否支持流,如果不支持,则将流的读取指针重置为原始的*位置。如果输入流不支持这一点,这个方法可能会失败*与一个IOException。

相反,表单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。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9973369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档