PipedOutputStream和PipedInputStream
关于PipedOutputStream和PipedInputStream的一些使用问题。
PipedOutputStream和PipedInputStream的用处
当需要同时处理输入和输出的时候,可以尝试使用Piple实现类似于生产者和消费者的角色功能。其中Pipe的OutputStream是生产组,用来接受数据并且写入Piple中,PipedInputStream类似消费者,从Pipe中读取数据。所以在PipedInputStream和PipedOutPutStream源代码中可以看到变量和方法的命名都是和writer和receiver相关的。
用法
一般来说我们需要使用两个线程分别处理Output和Input,就是说要在两个不同的线程中使用PipedOutputStream和PipedInputStream。
使用 PipledOutputStream.connect(PipedInputStream)
将两个管道连接在以前,这样PipedOutputStream会在接受到数据时调用PipedInputStream的receive方法从而实现将数据写入管道中。
常见错误信息
IOException(“Pipe not connected”)
如果只是实例化了PipedInputStream,但是没有调用connect方法(调用PipedInputStream 和PipedOutputStream的connect方法都是一样的效果),就会在InoutStream.read()方法中抛出这个异常。
IOException(“Pipe closed”)
如果PipedOutputStream调用了close方法之后,InputStream还是继续调用read()方法就会抛出这个异常。
IOException(“Write end dead”)
如果执行OutputStream的线程已经执行结束,但是没有调用PipedOutStream.close()。那么InputStream.read()方法就会抛出这个异常。解决方法就是负责生产数据的线程在执行完成之后应该马上调用PipedOutputStream.close()。
IOException(“Pipe broken”)
这个异常在多线程同时执行才会发生的典型错误,并且发生带有一定的偶然性。当PipedInputStream正在执行read()方法的时候,负责生产数据(持有PipedOutputStream)的线程执行结束了,但是并没有在线程结束的时候调用OutputStream的close方法,那么就有可能导致这个异常发生。
如何正确使用
- 首先必须要有两个线程分别负责PipedInputStream和PipedOutputStream
- 最好能在各自线程执行结束的时候关闭各自负责的Stream
- 在负责生成数据的线程执行完成之后一定要马上关闭PipedOutputStream