管道
提到管道,第一印象就是水管或者地下管道,一节接着一节,形如下图。
管道流
"流"从上一个管道 -------> 下一个管道。又细分为字节流和字符流。
字节流(PipedOutputStream、PipedInputStream)
如果从上一个管道到下一个管道,只是走个过场岂不是没有任何意义,既然要处理就需要逗留,逗留就意味着需要暂存,字节流使用字节数组存储,字符流使用字符数据存储。
PipedOutputStream 核心源码:
java
PipedOutputStream extends OutputStream
//指向下一节"管道"
private PipedInputStream sink;
//向外写数据(流出当前管道)
write(*****);
//构造方法
public PipedOutputStream(PipedInputStream snk) throws IOException {
connect(snk);
}
//连接下一个"管道"
public synchronized void connect(PipedInputStream snk) throws IOException {
if (snk == null) {
throw new NullPointerException();
//一个管道只能被一个管道连接
} else if (sink != null || snk.connected) {
throw new IOException("Already connected");
}
sink = snk;
snk.in = -1;
snk.out = 0;
//管道已被连接的标识
snk.connected = true;
}
PipedInputStream 核心源码:
java
PipedInputStream extends InputStream
//数据暂存的地方
protected byte buffer[];
//数组默认大小
private static final int DEFAULT_PIPE_SIZE = 1024;
//是否已经被连接的标识
boolean connected = false;
//构造方法
public PipedInputStream() {
initPipe(DEFAULT_PIPE_SIZE);
}
private void initPipe(int pipeSize) {
if (pipeSize <= 0) {
throw new IllegalArgumentException("Pipe Size <= 0");
}
buffer = new byte[pipeSize];
}
//自定义数组大小
public PipedInputStream(int pipeSize) {
initPipe(pipeSize);
}
//指定上一个"管道是谁"
public PipedInputStream(PipedOutputStream src) throws IOException {
this(src, DEFAULT_PIPE_SIZE);
}
//即指明上一个"管道是谁",又自定义数组大小
public PipedInputStream(PipedOutputStream src, int pipeSize)
throws IOException {
initPipe(pipeSize);
connect(src);
}
案例:一个字符串从上一个管道写到下一个管道。
java
public static void main(String[] args) throws IOException {
PipedOutputStream po = new PipedOutputStream();
PipedInputStream pi = new PipedInputStream();
Thread t1 = new Thread(() -> {
try {
int b;
while ((b = pi.read()) != -1) {
System.out.print((char) b);
}
pi.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
//链接管道
po.connect(pi);
String str1 = "hello world";
byte[] bytes = str1.getBytes();
Thread t2 = new Thread(() -> {
try {
po.write(bytes);
po.flush();
po.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
});
t2.start();
t1.start();
}
PipedReader、PipedWriter 字符管道类似于字节管道,只不过使用字符数组存储数据。