Java I/O 體系中,管道流(PipedInputStream/PipedOutputStream、PipedReader/PipedWriter)提供了一種線程間直接傳遞資料的機制,無需臨時檔案或共享記憶體。本文透過一個完整範例 pipeapp,示範如何利用管道串聯多個工作線程,完成資料的逐級轉換。
// 位元組管道
PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream(out);
// 字元管道
PipedWriter writer = new PipedWriter();
PipedReader reader = new PipedReader(writer);
流程:input.txt(每行 "x") → 執行緒 Y 轉 "y" → 執行緒 Z 轉 "z" → 主線程列印。
PipeAppimport java.io.*;
public class PipeApp {
public static void main(String[] args) {
PipeApp app = new PipeApp();
try (FileInputStream fis = new FileInputStream("input.txt")) {
InputStream yPipe = app.changeToY(fis);
InputStream zPipe = app.changeToZ(yPipe);
try (DataInputStream dis = new DataInputStream(zPipe)) {
String line;
System.out.println("=== 轉換結果 ===");
while ((line = dis.readLine()) != null) {
System.out.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 階段 1:x → y
public InputStream changeToY(InputStream in) throws IOException {
DataInputStream dis = new DataInputStream(in);
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
PrintStream ps = new PrintStream(pos);
new YThread(dis, ps).start();
return pis; // 回傳讀取端給下一階段
}
// 階段 2:y → z
public InputStream changeToZ(InputStream in) throws IOException {
DataInputStream dis = new DataInputStream(in);
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
PrintStream ps = new PrintStream(pos);
new ZThread(dis, ps).start();
return pis;
}
}
YThread / ZThreadimport java.io.*;
class YThread extends Thread {
private final DataInputStream in;
private final PrintStream out;
public YThread(DataInputStream in, PrintStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
try {
String line;
while ((line = in.readLine()) != null) {
out.println(line.replace('x', 'y'));
out.flush(); // 確保資料及時進入管道
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try { out.close(); } catch (Exception ignored) {}
}
}
}
// ZThread 結構相同,僅將 replace('x','y') 改為 replace('y','z')
PipedOutputStream 的 write 行為。close(),消費者才能讀到 -1/null 結束標記。管道流是 Java 線程間通訊的輕量級方案,適合「串流式、單向、生產-消費」模型。配合 DataInputStream/PrintStream 等裝飾器,能快速構建靈活的資料處理管線。