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

Java I/O 流核心概念全景解析:從位元組流到物件序列化

     編輯:Java 相關知識

流是 Java I/O 系統的核心抽象,無論是檔案讀寫、網路通訊還是程序間通訊,本質上都是在處理資料流。本文從基礎位元組流講起,層層遞進到字元流、緩衝流、物件序列化,構建完整知識體系。

一、位元組流基石:InputStream / OutputStream

所有位元組流的父類別,處理單位為「位元組」,適用於圖片、影音、二進位檔案等非文本資料。

核心概念

  • 輸入流:從資料源讀取位元組(InputStream)。
  • 輸出流:向目的地寫入位元組(OutputStream)。
  • 流的獲取:不同資料源有不同獲取方式。檔案用 FileInputStream,網路用 Socket.getInputStream()。

檔案讀取標準範式

try (InputStream is = new FileInputStream("c:/boot.ini")) {
    byte[] buffer = new byte[10240];
    int len;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    while ((len = is.read(buffer)) != -1) {
        baos.write(buffer, 0, len);
    }
    String content = baos.toString();
    System.out.println(content);
} catch (IOException e) {
    e.printStackTrace();
}

關鍵點:

  1. 使用 try-with-resources 自動關閉流(Java 7+),避免資源洩漏。
  2. 採用緩衝陣列 buffer 批量讀寫,避免單位元組操作效能極差。
  3. read() 返回實際讀取位元組數,-1 表示流結束。

檔案寫入範例

try (OutputStream os = new FileOutputStream("c:/now.txt")) {
    os.write(new Date().toString().getBytes());
    // try-with-resources 自動 flush 並 close
} catch (IOException e) {
    e.printStackTrace();
}

二、字元流:Reader / Writer

位元組流的裝飾者,專門處理「字元」資料,內部自動處理字元編碼轉換(預設 UTF-8),適用於文本檔案。

直接使用 FileReader

try (Reader reader = new FileReader("c:/boot.ini")) {
    char[] buffer = new char[10240];
    int count;
    StringBuilder sb = new StringBuilder();
    while ((count = reader.read(buffer)) != -1) {
        sb.append(buffer, 0, count);
    }
    System.out.println(sb.toString());
}

最佳實踐:BufferedReader 按行讀取

try (BufferedReader br = new BufferedReader(new FileReader("c:/boot.ini"))) {
    String line;
    StringBuilder sb = new StringBuilder();
    while ((line = br.readLine()) != null) {
        sb.append(line).append("\n");
    }
    System.out.println(sb.toString());
}

BufferedReader 內部有 8KB 預設緩衝區,readLine() 直接返回一行文本,無需手動處理換行符,是讀取文本檔的標準做法。

三、物件序列化:ObjectOutputStream / ObjectInputStream

將物件圖轉換為位元組序列(序列化),或從位元組序列重建物件(反序列化),支援物件持久化與網路傳輸。

核心要求

  • 類別必須實作 Serializable 介面(標記介面,無方法)。
  • 建議顯式宣告 serialVersionUID,避免版本不兼容導致 InvalidClassException。
  • transient 關鍵字標記不序列化欄位(如密碼、暫存計算結果)。

完整範例

// 定義可序列化類別
class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    private transient String password; // 不序列化
    // 建構子、getter/setter、toString()...
}

// 序列化寫入
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("persons.data"))) {
    oos.writeObject(new Person("張三", 23));
    oos.writeObject(new Person("李四", 24));
}

// 反序列化讀取
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("persons.data"))) {
    while (true) {
        try {
            Person p = (Person) ois.readObject();
            System.out.println(p);
        } catch (EOFException e) {
            break; // 讀取結束
        }
    }
}

四、流體系架構總覽

層級輸入輸出適用場景
節點流(資料源)FileInputStreamFileOutputStream檔案、記憶體陣列、網路 Socket
處理流(裝飾者)BufferedInputStream
ObjectInputStream
DataInputStream
BufferedOutputStream
ObjectOutputStream
DataOutputStream
緩衝、物件序列化、基本類型讀寫
字元流橋接InputStreamReader
FileReader
OutputStreamWriter
FileWriter
文本檔案處理(自動編碼轉換)
字元緩衝BufferedReaderBufferedWriter高效按行讀寫文本

五、實務避坑指南

  1. 一定要關閉流:使用 try-with-resources,確保即使拋出異常也能釋放資源。
  2. 指定編碼:new InputStreamReader(is, "UTF-8"),避免平台預設編碼不一致導致亂碼。
  3. 大檔案用緩衝:無論位元組還是字元流,都要套 BufferedInputStream/BufferedReader。
  4. 序列化慎用:會破壞封裝、增加耦合、版本演進困難。優先考慮 JSON、Protobuf 等跨語言格式。
  5. 區分位元組/字元:二進位檔用位元組流,文本檔用字元流,切勿混用。

掌握 Java 流體系,關鍵在於理解「裝飾者模式」如何層層包裝賦予新功能,並根據資料性質選擇正確的流組合。

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