Java之路:管道流
阿新 • • 發佈:2018-12-13
在UNIX/Linux中有一個很有用的概念——管道(pipe),它具有將一個程式的輸出當作另一個程式的輸入的能力。
在Java中,它的 I/O系統建立在資料流概念之上,也可以使用“管道”流進行執行緒之間的通訊,在這個機制中,輸入流和輸出流必須相連線,這樣的通訊有別於一般的共享資料(Shared Data)緩衝區通訊,其不需要一個共享的資料空間。
管道流主要用於連線兩個執行緒間的通訊。管道流也分為位元組流(PipedInputStream、PipedOutputStream)與字元流(PipedReader、PipedWriter)兩種型別.
一個PipedInputStream物件必須和一個PipedOutputStream物件進行連線而產生一個通訊管道, PipedOutputStream可以向管道中寫入資料,PipedInputStream可以從管道中讀取PipedOutputStream寫入的資料。
如下圖所示,這兩個類主要用來完成執行緒之間的通訊,一個執行緒的PipedInputStream物件能夠從另外一個執行緒的PipedOutputStream物件中讀取資料:
package com.xy.io;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipeStreamDemo {
public static void main(String[] args) {
try {
Sender sender = new Sender(); // 建立執行緒物件Sender
Receiver receiver = new Receiver(); // 建立執行緒物件Receiver
PipedOutputStream out = sender.getOutputStream(); // 寫入
PipedInputStream in = receiver.getInputStream(); // 讀出
out.connect(in); // 將輸出傳送到輸入
sender.start();// 啟動執行緒
receiver.start();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
class Sender extends Thread {
private PipedOutputStream out = new PipedOutputStream();
public PipedOutputStream getOutputStream() {
return out;
}
public void run() {
String s = new String("Receiver,你好!");
try {
out.write(s.getBytes());
out.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
class Receiver extends Thread {
private PipedInputStream in = new PipedInputStream();
public PipedInputStream getInputStream() {
return in;
}
public void run() {
String s = null;
byte[] b = new byte[1024];
try {
int len = in.read(b);
s = new String(b, 0, len);
System.out.println("收到了以下資訊:" + s);
in.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
【結果】
此外,注意到第48行,宣告的位元組陣列大小為1024,其實這是有講究的:
類PipedInputStream運用的是一個1024位元組固定大小的迴圈緩衝區。 實際上,寫入PipedOutputStream的資料儲存到對應的 PipedInputStream的內部緩衝區。如果對應的 PipedInputStream輸入緩衝區已滿,再次企圖寫入PipedOutputStream的執行緒都將被阻塞,直至出現讀取PipedInputStream的操作從緩衝區刪除資料。