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。