首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java IO 系統深度解析:流體系架構、裝飾者模式與實戰代碼詳解

     編輯:Java 相關知識

Java IO 核心哲學:一切皆流

java.io 核心抽象是 Stream (流):有序位元組/字符序列的來源 (Input) 或目的地 (Output)。所有資料經序列化寫入輸出流、或從輸入流讀取。設計核心採用 裝飾者模式:基礎流 (節點流) 對接物理設備 (檔案、記憶體、網路),處理流 (包裝流) 疊加功能 (緩衝、格式化、物件序列化、編碼轉換),靈活組合、動態擴展。

流體系完整分類架構

一、位元組流 — 處理二進制資料 (圖片、聲音、壓縮包、網路傳輸)

方向基礎節點流功能核心處理流 (裝飾者)功能
InputFileInputStream讀取檔案BufferedInputStream緩衝讀取,大幅提升效能
ByteArrayInputStream讀取記憶體 byte[]DataInputStream讀取基本類型 (int, double 等)
PipedInputStream執行緒間管道輸入ObjectInputStream反序列化物件 (配合 Serializable)
SequenceInputStream合併多個輸入流PushbackInputStream回推位元組 (編譯器/解析器用)
StringBufferInputStream (已棄用)讀取 StringBuffer--
OutputFileOutputStream寫入檔案BufferedOutputStream緩衝寫入,批次刷新
ByteArrayOutputStream寫入記憶體 byte[]DataOutputStream寫入基本類型
PipedOutputStream執行緒間管道輸出ObjectOutputStream序列化物件
SequenceOutputStream (JDK 內部)合併多個輸出流PrintStream格式化輸出 (System.out 即此類)

二、字符流 — 處理文本資料 (編碼感知:UTF-8, GBK 等)

字符流 = 位元組流 + InputStreamReader/OutputStreamWriter (編碼轉換橋樑)。

方向基礎節點流對應位元組流核心處理流功能
ReaderFileReaderFileInputStreamBufferedReader緩衝逐行讀取 (readLine())
StringReaderStringBufferInputStreamLineNumberReader追蹤行號
CharArrayReaderByteArrayInputStreamPushbackReader回推字符
PipedReaderPipedInputStream--
WriterFileWriterFileOutputStreamBufferedWriter緩衝寫入、newLine() 跨平台換行
StringWriter無直接對應PrintWriter格式化輸出 (含 println/printf)、不拋異常
CharArrayWriterByteArrayOutputStream--
PipedWriterPipedOutputStream--

三、關鍵轉換橋樑

  • InputStreamReader(InputStream in, Charset charset):位元組流 → 字符流 (指定編碼,**生產必須顯式指定編碼**)。
  • OutputStreamWriter(OutputStream out, Charset charset):字符流 → 位元組流。

四、隨機存取 — RandomAccessFile

  • 同時實現 DataInput/DataOutput,支援 seek(long pos) 任意位置讀寫。
  • 模式:"r" (唯讀)、"rw" (讀寫)、"rws"/"rwd" (同步寫入)。
  • 適用:大檔案斷點續傳、索引檔案、記憶體映射檔案替代方案。

實戰代碼全景示範 (涵蓋 6 大核心場景)

import java.io.*;

public class IODemo {
    public static void main(String[] args) throws IOException {
        // 1. 緩衝逐行讀取檔案 + 鍵盤輸入
        try (BufferedReader in = new BufferedReader(new FileReader("src/IODemo.java"));
             BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in))) {
            String line;
            while ((line = in.readLine()) != null) System.out.println(line);
            System.out.print("輸入一行: ");
            System.out.println("你輸入: " + stdin.readLine());
        }

        // 2. 從字串讀取 (字符流)
        String content = "Hello\nWorld";
        try (StringReader sr = new StringReader(content)) {
            int c;
            while ((c = sr.read()) != -1) System.out.print((char)c);
        }

        // 3. 記憶體格式化輸入 (位元組流 + DataInput)
        try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(content.getBytes()))) {
            while (true) System.out.print((char)dis.readByte());
        } catch (EOFException ignored) { System.out.println("\n--- 記憶體讀取結束 ---"); }

        // 4. 格式化輸出到檔案 (行號 + PrintWriter)
        try (BufferedReader br = new BufferedReader(new StringReader(content));
             PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("out.txt")))) {
            String l; int i=1;
            while ((l = br.readLine()) != null) out.println(i++ + ": " + l);
        }

        // 5. 基本類型序列化存儲與恢復 (DataOutput/Input + 緩衝)
        try (DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data.dat")))) {
            dos.writeDouble(Math.PI);
            dos.writeChars("\nPI via writeChars\n");
            dos.writeBytes("PI via writeBytes\n");
        }
        try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("data.dat")));
             BufferedReader br = new BufferedReader(new InputStreamReader(dis))) {
            System.out.println("Double: " + dis.readDouble());
            System.out.println("Chars: " + br.readLine());
            System.out.println("Bytes: " + br.readLine());
        }

        // 6. RandomAccessFile 隨機讀寫
        try (RandomAccessFile raf = new RandomAccessFile("random.dat", "rw")) {
            for (int i=0; i<10; i++) raf.writeDouble(i * 1.414);
            raf.seek(5 * 8); // 定位第 6 個 double
            raf.writeDouble(47.0001); // 修改
            for (int i=0; i<10; i++) System.out.println("Idx " + i + ": " + raf.readDouble());
        }
    }
}

核心設計模式與最佳實踐

  1. 裝飾者模式靈活組合: new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) — 職責單一、動態擴展、避免繼承爆炸。
  2. Try-with-resources (Java 7+) 強制關閉: 實作 AutoCloseable,編譯器自動生成 finally 關閉邏輯,**杜絕資源洩漏**。
  3. 緩衝是效能銀彈: 除極小資料量,**永遠包裝 BufferedInputStream/OutputStream/Reader/Writer**。磁盤 I/O 成本遠超記憶體複製。
  4. 編碼顯式化: **永不依賴平台預設編碼**。構造 Reader/Writer 時必須傳 StandardCharsets.UTF_8。
  5. 序列化慎用: ObjectOutputStream 產出二進制強耦合類結構、版本維護困難、安全風險 (反序列化漏洞)。**首選 JSON (Jackson/Gson)、Protobuf、Avro** 進行跨語言/版本數據交換。
  6. NIO.2 (java.nio.file) 替代舊 IO: Files.readAllLines(), Files.walk(), FileChannel 非阻塞 I/O、記憶體映射、檔案屬性/權限/監聽 (WatchService) 功能更強、API 更現代。

Java IO 體系雖歷經演進 (IO → NIO → NIO.2),但「流、裝飾者、緩衝、編碼、序列化」核心概念不變。深度理解其架構邏輯,配合現代 API 與最佳實踐,才能寫出高效、健壯、可維護的 I/O 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved