Java I/O 體系龐大(40+ 類),初學者常陷入「不知選哪個流」的困境。本文提供**三步決策法**、**裝飾者模式組合表**、**實戰場景對照表**,讓流選型變得機械化、標準化。
| 裝置 | 輸入流 | 輸出流 |
|---|---|---|
| 檔案 | FileInputStream | FileOutputStream |
| 檔案(文字) | FileReader | FileWriter |
| 記憶體陣列 | ByteArrayInputStream | ByteArrayOutputStream |
| 記憶體陣列(文字) | CharArrayReader | CharArrayWriter |
| 字串 | StringReader | StringWriter |
| 網路 Socket | socket.getInputStream() | socket.getOutputStream() |
| 標準輸入/輸出 | System.in | System.out / System.err |
| 管道(執行緒間) | PipedInputStream | PipedOutputStream |
| 場景 | 標準組合 | 關鍵點 |
|---|---|---|
| 複製二進位檔案 | FileInputStream → BufferedInputStream → BufferedOutputStream → FileOutputStream | 緩衝區大小 8KB-64KB |
| 讀取文字檔案(逐行) | FileReader → BufferedReader → readLine() | 指定編碼 UTF-8 |
| 寫入文字檔案 | FileWriter → BufferedWriter → write()/newLine() | flush() 確保落盤 |
| 物件序列化/反序列化 | ObjectOutputStream/ObjectInputStream + Buffered | 實作 Serializable、serialVersionUID |
| 資料型別讀寫 | DataOutputStream/DataInputStream + Buffered | 順序一致、UTF-8 字串 |
| 壓縮/解壓縮 | GZIPOutputStream/GZIPInputStream + Buffered | 大檔案分塊處理 |
| 網路通訊 | Socket.getInputStream()/getOutputStream() + Buffered | 設定 SO_TIMEOUT、KeepAlive |
| 控制台互動 | System.in → InputStreamReader → BufferedReader / Scanner | Scanner 適合分詞,BufferedReader 適合逐行 |
| 記憶體高速緩衝 | ByteArrayOutputStream / ByteArrayInputStream | 避免磁碟 IO、單元測試 Mock |
| 隨機存取檔案 | RandomAccessFile ("rw") | seek() 定位、支援斷點續傳 |
// 讀取全部行
List lines = Files.readAllLines(Paths.get("data.txt"), StandardCharsets.UTF_8);
// 串流處理大檔案
try (Stream lines = Files.lines(Paths.get("big.log"), StandardCharsets.UTF_8)) {
lines.filter(l -> l.contains("ERROR")).forEach(System.out::println);
}
// 複製/移動/刪除
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
Files.move(src, dest, StandardCopyOption.ATOMIC_MOVE);
Files.deleteIfExists(path);
try (FileChannel in = FileChannel.open(Paths.get("src"), StandardOpenOption.READ);
FileChannel out = FileChannel.open(Paths.get("dest"), StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
// 直接通道傳輸(零拷貝,OS 級優化)
in.transferTo(0, in.size(), out);
// 或 MappedByteBuffer(記憶體映射,超大檔案)
MappedByteBuffer buffer = in.map(FileChannel.MapMode.READ_ONLY, 0, in.size());
out.write(buffer);
}
**三步決策法(流向 → 型別 → 裝置)+ 裝飾者組合(緩衝必加 + 功能按需)+ NIO.2 現代 API** 構成完整選型體系。將 40+ 流類歸納為「節點流(源/目的)」與「處理流(裝飾者)」兩大類,掌握標準組合模式,I/O 選型不再是難題。