PipedOutputStream 类可将字节流写入 Java 管道输出流。
管道输出流能够与管道输入流相连接,从而构建起一个通信管道。其中,管道输出流充当管道的发送端。一般情况下,数据由某个线程写入到 PipedOutputStream 对象中,与此同时,另一个线程从与之连接的 PipedInputStream 读取数据。
注意:不推荐在单个线程中同时使用 PipedOutputStream 和 PipedInputStream 两个对象,因为这极有可能引发线程死锁问题(因为 read() 和 write() 方法会阻塞)。若从连接的管道输入流读取数据的线程不再处于活动状态,那么该管道即被视为已损坏 。如下图:

以下是一个简单的 PipedOutputStream 示例:
package com.hxstrive.java_io.pipe;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
* 管道流示例
* @author hxstrive
*/
public class PipeDemo1 {
public static void main(String[] args) throws IOException {
// 创建管道流对象
final PipedOutputStream output = new PipedOutputStream();
final PipedInputStream input = new PipedInputStream(output);
// 线程1,向管道中写入数据
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
// 向管道写入一个字节数组
output.write("Hello world, pipe!".getBytes());
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
// 线程2,从管道中读取数据
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
// 读取数据,一次读一个字节
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
// 输出:Hello world, pipe!
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
// 启动线程
thread1.start();
thread2.start();
}
}上述代码中,PipedOutputStream 的 write() 方法接收一个 int,其中包含要写入的字节的字节值。
📢需要注意的是,尽管参数类型是 int,但实际上该方法只会处理这个 int 值的低 8 位,也就是只关注其表示一个字节的数据部分。这是因为在 Java 里,字节数据通常是 8 位的,而 int 类型是 32 位。当我们调用 write() 方法时,会把这个 int 参数进行截断,只取其低 8 位来作为要写入管道输出流的字节数据。
由于 PipedOutputStream 是 OutputStream 的子类,因此 PipedOutputStream 具有与 OutputStream 相同的基本方法。
以下是 PipedOutputStream 类一些常用方法:
write(int b) 该方法的作用是把指定的字节写入到管道输出流。尽管参数 b 为 int 类型,但实际只会处理其低 8 位。
write(byte[] b, int off, int len) 此方法会将字节数组 b 里从偏移量 off 开始的 len 个字节写入到管道输出流。
close() 调用该方法可以关闭管道输出流,同时释放与之关联的所有系统资源。
flush() 这个方法用于刷新管道输出流,强制将缓冲区内的所有字节写入到管道中。
connect(PipedInputStream snk) 该方法用于将此管道输出流连接到指定的管道输入流 snk。若输出流已连接到其他输入流,则会抛出 IOException。