PipedInputStream – 如何避免“java.io.IOException:Pipe broken”
我有两个主题。 其中一个写入PipedOutputStream,另一个从相应的PipedInputStream读取。 背景是一个线程正在从远程服务器下载一些数据,并通过管道流将其多路复用到其他几个线程。
问题是有时(特别是在下载大型(> 50Mb)文件时)我得到java.io.IOException:试图从PipedInputStream读取时管道坏了 。
Javadoc说, A pipe is said to be broken if a thread that was providing data bytes to the connected piped output stream is no longer alive.
确实,我的写作线程在将所有数据写入PipedOutputStream之后真的死了。
有解决方案? 如何防止PipedInputStream抛出此exception? 我希望能够读取写入PipedOutputStream的所有数据,即使编写线程完成了他的工作。 ( 如果有人知道如何继续写线程直到所有数据都被读取,这个解决方案也是可以接受的 )。
使用java.util.concurrent.CountDownLatch,并且在第二个线程发出信号已完成从管道读取之前,不要结束第一个线程。
更新:快速和脏代码,以说明我的评论如下
final PipedInputStream pin = getInputStream(); final PipedOutputStream pout = getOutputStream(); final CountDownLatch latch = new CountDownLatch(1); InputStream in = new InputStream() { @Override public int read() throws IOException { return pin.read(); } @Override public void close() throws IOException { super.close(); latch.countDown(); } }; OutputStream out = new OutputStream(){ @Override public void write(int b) throws IOException { pout.write(b); } @Override public void close() throws IOException { while(latch.getCount()!=0) { try { latch.await(); } catch (InterruptedException e) { //too bad } } super.close(); } }; //give the streams to your threads, they don't know a latch ever existed threadOne.feed(in); threadTwo.feed(out);
当你正在使用它的线程结束时,你关闭了PipedOutputStream
吗? 您需要这样做,以便将其中的字节刷新到相应的PipedInputStream
。
PipedInputStream
和PipedOutputStream
被破坏(关于线程)。 他们假设每个实例都绑定到一个特定的线程。 这很奇怪。 我建议使用您自己的(或至少是不同的)实现。