首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PipedInputStream包装BufferedInputStream

用PipedInputStream包装BufferedInputStream
EN

Stack Overflow用户
提问于 2011-02-09 21:40:15
回答 1查看 3K关注 0票数 4

我有一个需要阅读的OutputStream,所以我使用了以下(Groovy)代码来获取对数据的InputStream引用:

代码语言:javascript
复制
PipedInputStream inputStream = new PipedInputStream()
    PipedOutputStream outputStream = new PipedOutputStream(inputStream)
    new Thread(
            new Runnable() {
                public void run() {
                    // Some API method
                    putDataInOutputStream(outputStream)
                    outputStream.close()
                }
            }
    ).start()

handler.process(inputStream)

在本例中,处理程序是实现具有以下方法的接口的类:

代码语言:javascript
复制
public void process(InputStream stream);

在我们的新需求中出现的问题是流上有一些预处理,因此我需要在handler.process()方法中至少读两次流。下面是一个实现的一些示例代码:

代码语言:javascript
复制
public void process(InputStream stream) {
    def bufferedStream = new BufferedInputStream(stream, 30 * 1048576)  // 30 MB
    bufferedStream.mark(Integer.MAX_VALUE)
    parseMetadata(bufferedStream)
    bufferedStream.reset()
    doTheThingYouDo(bufferedStream)
 }

我知道,对于某些输入,我是,而不是,达到了30 MB的限制或缓冲区大小。但是,我总是得到以下例外:

代码语言:javascript
复制
java.io.IOException: Stream closed

这有可能吗?我认为问题在于PipedOutputStream上的线程即将结束,但我不知道如何防止这种情况,或者可能是因为我是Java的新手而造成更多的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-02-09 23:07:37

我最好的猜测是,您的parseMetadata以某种方式关闭了流。我试过你的方案了,对我来说很好。通常,在处理程序完成之前关闭OutputStream不是问题,这正是管道流的目的所在。

此外,鉴于你的情况,我会省略管道,和额外的螺纹。如果您不介意将整个流保存在内存中,您可以这样做

代码语言:javascript
复制
ByteArrayOutputStream out = new ByteArrayOutputStream();

fillTheOutput(out);

ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

pass1(in);
in.reset();
pass2(in);

如果您不介意内存中的所有东西,那么无论如何您都有麻烦了,因为您的BufferedInputStream所做的事情大致相同。

编辑:请注意,您可以轻松地基于字节数组构建一个新的ByteArrayInputStream,这是常规流不能做的事情。

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

https://stackoverflow.com/questions/4950814

复制
相关文章

相似问题

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