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

Java 進階教程:IO 流體系架構與裝飾器模式實戰

     編輯:Java 相關知識

Java IO 設計哲學

Java IO 採用裝飾器模式構建靈活的流管道。不同於其他語言的「一行代碼讀文件」,Java 需組合多個流對象,但獲得了極大的靈活性:可自由組合「數據源 → 轉換 → 緩衝 → 格式化」等功能層。

四大基類與繼承體系

基類方向數據類型典型子類
InputStream讀字節FileInputStream, ByteArrayInputStream, GZIPInputStream
OutputStream寫字節FileOutputStream, ByteArrayOutputStream, GZIPOutputStream
Reader讀字符 (Unicode)FileReader, BufferedReader, InputStreamReader
Writer寫字符 (Unicode)FileWriter, BufferedWriter, OutputStreamWriter

核心裝飾器類

裝飾器包裝目標功能
BufferedInputStream/ReaderInputStream/Reader緩衝讀取,減少系統調用
BufferedOutputStream/WriterOutputStream/Writer緩衝寫入,批量刷新
InputStreamReaderInputStream字節流 → 字符流 (指定編碼)
OutputStreamWriterOutputStream字符流 → 字節流 (指定編碼)
DataInputStream/DataOutputStreamInputStream/OutputStream基本類型讀寫 (int, double 等)
ObjectInputStream/ObjectOutputStreamInputStream/OutputStream對象序列化/反序列化
GZIPInputStream/GZIPOutputStreamInputStream/OutputStream壓縮/解壓
LineNumberReaderReader行號追蹤
PushbackInputStream/ReaderInputStream/Reader回退/預讀

經典組合模式

文本文件讀取 (標準模式)


// 現代寫法 (Java 7+ try-with-resources)
try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
            new FileInputStream("file.txt"), StandardCharsets.UTF_8))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
}

層次:FileInputStream(字節源) → InputStreamReader(解碼) → BufferedReader(緩衝+按行讀取)

文本文件寫入


try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream("out.txt"), StandardCharsets.UTF_8))) {
    bw.write("Hello World");
    bw.newLine();
    bw.write("你好世界");
}

二進制文件複製 (高效)


try (FileInputStream in = new FileInputStream("src.dat");
     FileOutputStream out = new FileOutputStream("dest.dat")) {
    byte[] buffer = new byte[8192];
    int len;
    while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
    }
}

壓縮文件讀取


try (DataInputStream dis = new DataInputStream(
        new GZIPInputStream(
            new FileInputStream("data.gz")))) {
    int value = dis.readInt();
    double d = dis.readDouble();
}

層次:FileInputStream → GZIPInputStream(解壓) → DataInputStream(基本類型讀取)

關鍵技術細節

緩衝機制

  • 內存中開闢緩衝區 (默認 8KB)
  • 讀:一次性從底層填滿緩衝區,後續從緩衝區取
  • 寫:先寫緩衝區,滿或 flush 時才刷到底層
  • 大幅減少昂貴的系統調用 / 磁盤 I/O

字符編碼

  • 必須顯式指定編碼:StandardCharsets.UTF_8
  • 避免使用 FileReader/FileWriter (平台默認編碼,不可移植)
  • InputStreamReader/OutputStreamWriter 是字節與字符的橋樑

System.arraycopy vs Arrays.copyOf


// 底層高效複製,native 實現 (memmove)
System.arraycopy(src, srcPos, dest, destPos, length);

// 包裝層,創建新數組並複製
Arrays.copyOf(original, newLength);

IO 內部大量使用 System.arraycopy 進行緩衝區管理。

異常處理最佳實踐


// Java 7+ try-with-resources 自動關閉 (實現 AutoCloseable)
try (Resource r1 = ...; Resource r2 = ...) {
    // 使用資源
} catch (IOException e) {
    // 處理異常
}
// 無需 finally 手動 close,即使異常也會關閉

NIO.2 現代文件操作 (Java 7+)


// Files 工具類:一行代碼完成常見操作
List lines = Files.readAllLines(Paths.get("file.txt"), StandardCharsets.UTF_8);
Files.write(Paths.get("out.txt"), lines, StandardCharsets.UTF_8);
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
Files.move(src, dest);
Files.delete(path);
Stream lines = Files.lines(Paths.get("big.txt")); // 流式處理大文件

序列化與反序列化


class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private transient String password; // 不序列化
    // ...
}

// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
    oos.writeObject(user);
}

// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
    User u = (User) ois.readObject();
}

總結

Java IO 通過四大基類和豐富的裝飾器,構建了功能強大、組合靈活的流體系。核心掌握點:

  1. 字節流 vs 字符流:二進制用 Stream,文本用 Reader/Writer + 顯式編碼
  2. 裝飾器組合順序:源 → 轉換 → 緩衝 → 功能增強
  3. 緩衝是性能關鍵:務必加 Buffered
  4. try-with-resources:資源安全釋放標準寫法
  5. NIO.2 Files:簡單操作首選,複雜流式處理用 Stream

理解裝飾器模式在 IO 中的應用,不僅能熟練使用 Java IO,更能領會「組合優於繼承」的設計智慧。

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