我有一个需要阅读的OutputStream,所以我使用了以下(Groovy)代码来获取对数据的InputStream引用:
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)在本例中,处理程序是实现具有以下方法的接口的类:
public void process(InputStream stream);在我们的新需求中出现的问题是流上有一些预处理,因此我需要在handler.process()方法中至少读两次流。下面是一个实现的一些示例代码:
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的限制或缓冲区大小。但是,我总是得到以下例外:
java.io.IOException: Stream closed这有可能吗?我认为问题在于PipedOutputStream上的线程即将结束,但我不知道如何防止这种情况,或者可能是因为我是Java的新手而造成更多的问题。
发布于 2011-02-09 23:07:37
我最好的猜测是,您的parseMetadata以某种方式关闭了流。我试过你的方案了,对我来说很好。通常,在处理程序完成之前关闭OutputStream不是问题,这正是管道流的目的所在。
此外,鉴于你的情况,我会省略管道,和额外的螺纹。如果您不介意将整个流保存在内存中,您可以这样做
ByteArrayOutputStream out = new ByteArrayOutputStream();
fillTheOutput(out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
pass1(in);
in.reset();
pass2(in);如果您不介意内存中的所有东西,那么无论如何您都有麻烦了,因为您的BufferedInputStream所做的事情大致相同。
编辑:请注意,您可以轻松地基于字节数组构建一个新的ByteArrayInputStream,这是常规流不能做的事情。
https://stackoverflow.com/questions/4950814
复制相似问题