java.io.IOException: Pipe closed

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.io.IOException: Pipe closed相关的知识,希望对你有一定的参考价值。

使用PipedOutputStream发送数据到PipedInputStream,从本地读取txt文件,如果文件里的数据太大就会出现java.io.IOException: Pipe closed;
下面是我的代码

求完整的解答思路!

建议打开DEBUG模式,一行行的排查,看看在哪行报错。理论上不会因为文件大而关闭流,如果大那也是内存溢出。追问

调试了很多次,不知道如何解决

追答

你这么做一下,把io关闭的地方都写在finally里面,别写在try里面试试。
把inputThread.start()和outpuThread.start()换一下执行顺序。

参考技术A 先fileInputStream.close;再outPutstream.close();追问

一样,还是报这个错..

追答

ouputStream write完后 flush();

参考技术B

public static void main(String[] args)


参考技术C 最后怎么解决的呀! 参考技术D 要不你把jvm的虚拟内存配置大一些看看呢追问

这个跟虚拟机的内存关系不大吧,文件十几KB就出这个异常了!

追答

只有在start的时候才会执行run的方法,run的方法又是结束的时候才关闭in或者outputstream,得看到更多代码才能确定问题,能发全部的代码吗?

追问

这就是全部的代码了,没有其他代码了

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抛出此异常?我希望能够读取写入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

另一答案

PipedInputStreamPipedOutputStream被打破(关于线程)。他们假设每个实例都绑定到一个特定的线程。这很奇怪。我建议使用您自己的(或至少是不同的)实现。

另一答案

当您使用多个读取器或编写器线程时,您可能会遇到这些类的问题(请参阅JDK-4028322)。

但是大多数用户可能只使用一个阅读器和一个编写器线程。既然你也是这种情况,那么你遇到破裂的管道的原因很可能就是你写完后你没有close PipedOutputStream

PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(out);

// You can of course also use an Executor or similar for this
new Thread(() -> {
    // Your method writing the data
    writeDataTo(out);
    // Close PipedOutputStream so that reader knows that the end of the data 
    // has been reached
    try {
        out.close();
    }
    catch (IOException e) {
        // Handle exception or simply ignore it; current implementation will NEVER 
        // throw an IOException: https://github.com/openjdk/jdk/blob/0e14d5a98453407488057e6714f90f04d7dfa383/src/java.base/share/classes/java/io/PipedOutputStream.java#L174
    }
}).start();

// Your method reading the data
readDataFrom(in);
// Close PipedInputStream so that writer fails instead of blocking infinitely in case 
// it tries to write again (for whatever reason)
in.close();

也没有必要手动调用PipedOutputStream.flush(),它只通知等待的读者,但如果直接调用close(),则不会丢失任何数据。

可悲的是,文档目前还不是很清楚所有这些。一般来说,依靠实现并不是一个好主意,但在这种情况下,它可能是唯一明智的解决方案:

以上是关于java.io.IOException: Pipe closed的主要内容,如果未能解决你的问题,请参考以下文章

避免日志充满 java.io.IOException: Broken pipe

java.io.IOException: Pipe closed

PipedInputStream - 如何避免“java.io.IOException:Pipe broken”

java.io.IOException: Broken pipe

openTSDB ConnectionManager: Unexpected exception from downstream java.io.IOException: Broken pipe(示

深入TCP协议底层解读Broken pipe产生的根因