1. 管道流
● 管道流仅用于多个线程之间传递信息,若用在同一个线程中可能会造成死锁;
● 管道流的输入输出是成对的,一个输出只能对应一个输入流,使用构造函数或者connect函数进行连接;
● 一对管道流包含一个缓冲区,默认值为1024个字节,若要改变缓冲区大小,可以使用带有参数的构造函数;
● 管道的读写操作是互相阻塞的,当缓冲区为空读操作阻塞;当缓冲区满时,写操作阻塞;
● 管道依附于线程,因此若线程结束,则虽然管道流对象还在,仍然会报错"read dead end";
● 管道流的读取方法与普通流不同,只有输出流正确close时,输出流才能读到-1值
2. 建立管道连接
- connect:
pipedInputStream.connect(pipedOutputStream);
pipedOutputStream.connect(pipedInputStream);
- 构造函数:
new pipedInputStream(pipedOutputStream);
new pipedOutputStream(pipedInputStream);
1)字符管道流:PipeReader 和 PipeWriter
2)字节管道流:
PipedInputStream():字节管道输入流 输入方法:write(byte [] b,int off,int len):将len字节从初始偏移量为off的指定byte数组写入该管道输出流 PipeInputStream读取文件后,读取的数据都存在了PipeInputStream对象的实例中,且类型为byte PipedOutputStream():字节管道输出流 输出方法:将连接的PipeOutputStream对象实例的输入流的数据,通过read方法,把内容读取到数组中 int read(byte [] b,int off,int len);将最多len个数据字节从此管道输入流读入到byte数组
3. 示例
package cn.itcast.io.p5.piped; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; public class pipedStream { public static void main(String[] args) throws IOException { PipedInputStream input = new PipedInputStream(); PipedOutputStream output = new PipedOutputStream(); output.connect(input);// 连接两个流,使读取流读取写入流的数据 // 使用线程相结合才能使用管道流 new Thread(new Input(input)).start(); new Thread(new Output(output)).start(); } } class Input implements Runnable { private PipedInputStream in; public Input(PipedInputStream in) { super(); this.in = in; } @Override public void run() { try { byte buf[] = new byte[1024]; int len = in.read(buf); String str = new String(buf, 0, len); System.out.println(str); in.close(); } catch (IOException e) { e.printStackTrace(); } } } class Output implements Runnable { private PipedOutputStream out; public Output(PipedOutputStream out) { super(); this.out = out; } @Override public void run() { try { // 使写入流的线程睡眠10秒 Thread.sleep(10000); out.write("小强小强小强小强小强小强小强小强小强小强小强小强小强小强小强".getBytes()); out.close(); } catch (Exception e) { // TODO: handle exception } } }