PipedInputStream - 如何避免“java.io.IOException:Pipe broken” [英] PipedInputStream - How to avoid "java.io.IOException: Pipe broken"

查看:1500
本文介绍了PipedInputStream - 如何避免“java.io.IOException:Pipe broken”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个主题。其中一个写入PipedOutputStream,另一个从相应的PipedInputStream读取。背景是一个线程正在从远程服务器下载一些数据,并通过管道流将其多路复用到其他几个线程。

I have two threads. One of them writes to PipedOutputStream, another one reads from corresponding PipedInputStream. Background is that one thread is downloading some data from remote server and multiplexes it to several other threads through piped streams.

问题是有时(特别是在下载大型(> 50Mb)文件时)我得到 java.io.IOException:Pipe尝试从PipedInputStream读取时破坏

Javadoc说如果一个为连接的管道输出流提供数据字节的线程,则说管道被破坏了不再活着。

这是真的,我的写作线程在将所有数据写入PipedOutputStream之后真的死了。

The problem is that sometimes (especially when downloading large (>50Mb) files) I get java.io.IOException: Pipe broken when trying to read from PipedInputStream.
Javadoc says that 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.
It is true, my writing thread really dies after writing all his data to PipedOutputStream.

任何解决方案?如何防止PipedInputStream抛出此异常?我希望能够读取写入PipedOutputStream的所有数据,即使编写线程完成了他的工作。 (如果有人知道如何继续写线程直到所有数据都被读取,这个解决方案也是可以接受的)。

Any solutions? How can I prevent PipedInputStream from throwing this exception? I want to be able to read all data that was written to PipedOutputStream even if writing thread finished his work. (If anybody knows how to keep writing thread alive until all data will be read, this solution is also acceptable).

推荐答案

使用java.util.concurrent.CountDownLatch,并且在第二个线程发出信号从管道读完之前不要结束第一个线程。

Use a java.util.concurrent.CountDownLatch, and do not end the first thread before the second one has signaled that is has finished reading from the pipe.

更新:快速而脏的代码来说明我的评论

Update: quick and dirty code to illustrate my comment below

    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);

这篇关于PipedInputStream - 如何避免“java.io.IOException:Pipe broken”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆