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

Java IO 體系深度解析:流分類、層次結構與核心類實戰指南

     編輯:Java 綜合教學

Java IO 體系深度解析:從流概念到實戰應用

Java IO 是 Java 核心類庫中最基礎、也是最龐大的子系統之一。掌握其設計哲學(裝飾器模式)、流分類體系及核心類用法,是高效處理文件、網絡、內存數據的關鍵。本文系統梳理 Java IO 核心知識點,並附帶實戰代碼模板。

一、 核心概念:什麼是流?

流 是對數據傳輸過程的抽象,代表「有能力產出數據的源」或「有能力接收數據的終點」。

  • 輸入流:數據從源(文件、網絡、內存)流向程序(read())。
  • 輸出流:數據從程序流向目的地(write())。
  • 方向始終相對於程序(內存)。

二、 流的兩大分類維度

1. 按數據單位:字節流 vs 字符流

維度字節流字符流
基本單位Byte (8 bit)Char (16 bit, UTF-16)
頂級父類InputStream / OutputStreamReader / Writer
適用場景圖片、視頻、二進制文件、網絡傳輸文本文件、字符串處理
核心橋梁InputStreamReader / OutputStreamWriter(指定 Charset)

原則:字節流是萬能的(一切皆字節),字符流是為了處理文本而生的便利封裝。

2. 按功能角色:節點流 vs 處理流(裝飾器流)

  • 節點流:直接連接數據源/目的地(如 FileInputStream、FileReader)。
  • 處理流:套接在節點流或其他處理流上,提供增強功能(緩沖、轉換、數據類型讀寫、行號追蹤等)。
  • 設計模式:典型的裝飾器模式——動態組合,功能疊加。例如:new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))。

三、 核心類層次結構速查

字節流體系

InputStream (抽象)
├── FileInputStream          // 文件輸入
├── ByteArrayInputStream     // 內存字節數組輸入
├── PipedInputStream         // 管道輸入(線程間通信)
├── ObjectInputStream        // 對象反序列化
├── FilterInputStream (裝飾器基類)
│   ├── BufferedInputStream  // 緩沖輸入(關鍵:mark/reset)
│   ├── DataInputStream      // 基本類型讀取 (readInt, readUTF...)
│   └── PushbackInputStream  // 回退一字節
└── SequenceInputStream      // 多流串聯

OutputStream (抽象)
├── FileOutputStream
├── ByteArrayOutputStream    // 內存輸出,toByteArray()
├── PipedOutputStream
├── ObjectOutputStream       // 對象序列化
├── FilterOutputStream
│   ├── BufferedOutputStream // 緩沖輸出
│   ├── DataOutputStream     // 基本類型寫入
│   └── PrintStream          // System.out 本質

字符流體系

Reader (抽象)
├── FileReader               // 便捷類,默認編碼
├── BufferedReader           // 緩沖讀取,核心方法 readLine()
├── InputStreamReader        // 字節→字符橋梁(指定編碼)
├── StringReader             // 字符串源
├── PipedReader
├── LineNumberReader         // 帶行號
└── PushbackReader

Writer (抽象)
├── FileWriter
├── BufferedWriter           // 緩沖寫入,newLine()
├── OutputStreamWriter       // 字符→字節橋梁
├── PrintWriter              // 格式化打印,不拋異常
├── StringWriter             // 輸出到字符串
└── CharArrayWriter

四、 實戰代碼模板:高頻場景最佳實踐

1. 文本文件高效讀取(推薦)

public static String readFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(
            new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8))) {
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append(System.lineSeparator());
        }
        return sb.toString();
    }
}

2. 文本文件高效寫入

public static void writeFile(String path, String content) throws IOException {
    try (PrintWriter pw = new PrintWriter(
            new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(path), StandardCharsets.UTF_8)))) {
        pw.print(content);
    }
}

3. 二進制文件拷貝(大文件必用緩沖)

public static void copyBinary(String src, String dest) throws IOException {
    try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
         BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest))) {
        byte[] buffer = new byte[8192]; // 8KB
        int len;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
    }
}

4. 對象序列化與反序列化

// 寫對象 (要求實現 Serializable)
public static void writeObject(Serializable obj, String file) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(
            new BufferedOutputStream(new FileOutputStream(file)))) {
        oos.writeObject(obj);
    }
}

// 讀對象
public static Object readObject(String file) throws IOException, ClassNotFoundException {
    try (ObjectInputStream ois = new ObjectInputStream(
            new BufferedInputStream(new FileInputStream(file)))) {
        return ois.readObject();
    }
}

5. 內存流操作:字符串與字節數組互轉

// String -> byte[] (指定編碼)
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);

// byte[] -> String
String str = new String(bytes, StandardCharsets.UTF_8);

// 內存流管道示例
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintWriter pw = new PrintWriter(baos)) {
    pw.println("Hello Memory");
}
byte[] data = baos.toByteArray();

五、 避坑指南與性能優化建議

  1. 務必使用緩沖流:直接操作 FileInputStream 逐字節讀寫極慢,外層包裹 BufferedInputStream/OutputStream 或 BufferedReader/Writer。
  2. 指定字符集:構造 InputStreamReader/OutputStreamWriter 時顯式指定 StandardCharsets.UTF_8,避免跨平台亂碼。
  3. Try-with-resources:JDK 7+ 必須使用,自動關閉資源,防止句柄洩漏。
  4. 大文件處理:避免一次性 readAllBytes() 導致 OOM,採用流式分塊處理或 NIO FileChannel + MappedByteBuffer(零拷貝)。
  5. 序列化版本控制:實現 Serializable 的類務必顯式聲明 serialVersionUID。

六、 總結

Java IO 雖類繁多,但核心邏輯清晰:源頭/終點(節點流)+ 功能增強(處理流/裝飾器)。掌握四大抽象基類、橋梁轉換類、緩沖類、數據類型讀寫類,即可應對 90% 業務場景。現代項目中,NIO.2 (Files, Paths) 和第三方庫(Apache Commons IO, Google Guava)提供了更便捷的高級 API,建議作為首選,底層原理仍是本文所述經典 IO 模型。

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