管道連接輸入流和輸出流。
管道I/O
基于生產(chǎn)者 - 消費(fèi)者模式,其中生產(chǎn)者產(chǎn)生數(shù)據(jù),而消費(fèi)者消費(fèi)數(shù)據(jù)。在管道I/O
中,創(chuàng)建兩個(gè)流代表管道的兩端。 PipedOutputStream
對(duì)象表示流的一端,PipedInputStream
對(duì)象則表示流的另一端。使用兩個(gè)對(duì)象的connect()
方法連接兩端。
還可以通過(guò)在創(chuàng)建另一個(gè)對(duì)象時(shí)將一個(gè)對(duì)象傳遞給構(gòu)造函數(shù)來(lái)連接它們。以下代碼顯示了創(chuàng)建和連接管道兩端的兩種方法:
第一種方法創(chuàng)建管道輸入和輸出流并連接它們。 它使用connect()
方法連接兩個(gè)流。
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos); /* Connect the two ends */
第二種方法創(chuàng)建管道輸入和輸出流并連接它們。 它通過(guò)將輸入管道流傳遞到輸出流構(gòu)造器來(lái)連接兩個(gè)流。
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
可以在連接管道的兩端后生成和使用數(shù)據(jù)。通過(guò)使用PipedOutputStream
對(duì)象的write()
方法產(chǎn)生數(shù)據(jù)。無(wú)論對(duì)管道輸出流寫入什么,可自動(dòng)使用管道輸入流對(duì)象進(jìn)行讀取。
使用PipedInputStream
的read()
方法從管道讀取數(shù)據(jù)。如果數(shù)據(jù)在嘗試從管道讀取時(shí)不可用,則管道輸入流被阻止。
管道流具有固定容量的緩沖器,以在寫入管道和從管道讀取之間存儲(chǔ)數(shù)據(jù)。
當(dāng)創(chuàng)建管道時(shí),可以設(shè)置管道容量。 如果管道的緩沖區(qū)已滿,則嘗試在管道上寫入將會(huì)被阻止。
以下代碼創(chuàng)建緩沖區(qū)容量為2048
字節(jié)的管道輸入和輸出流。
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos, 2048);
管道用于將數(shù)據(jù)從一個(gè)線程傳輸?shù)搅硪粋€(gè)線程。兩個(gè)線程之間的同步由阻塞讀和寫來(lái)處理。
以下代碼演示如何使用管道I/O
。
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class Main {
public static void main(String[] args) throws Exception {
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pos.connect(pis);
Runnable producer = () -> produceData(pos);
Runnable consumer = () -> consumeData(pis);
new Thread(producer).start();
new Thread(consumer).start();
}
public static void produceData(PipedOutputStream pos) {
try {
for (int i = 1; i <= 50; i++) {
pos.write((byte) i);
pos.flush();
System.out.println("Writing: " + i);
Thread.sleep(500);
}
pos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void consumeData(PipedInputStream pis) {
try {
int num = -1;
while ((num = pis.read()) != -1) {
System.out.println("Reading: " + num);
}
pis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面的代碼生成以下結(jié)果。
Reading: 1
Writing: 1
Writing: 2
Reading: 2
Reading: 3
Writing: 3
Writing: 4
Reading: 4
Writing: 5
Reading: 5
Writing: 6
Reading: 6
Reading: 7
Writing: 7
Writing: 8
Reading: 8
Reading: 9
Writing: 9
Writing: 10
Reading: 10
Writing: 11
Reading: 11
Writing: 12
... ...