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

Java IO 體系全景圖:從流分類到裝飾者模式實戰

     編輯:Java 相關知識

流的兩大維度分類

維度字節流 (Byte Stream)字符流 (Char Stream)
基本單位1 byte (8 bits)1 char (UTF-16 code unit, 2 bytes)
基類InputStream / OutputStreamReader / Writer
典型用途圖片、視頻、二進制數據、網絡傳輸文本文件、XML、JSON、控制台交互

節點流 (Node Streams) —— 直接連接數據源/目的地

類型字節流字符流說明
內存ByteArrayInputStream / ByteArrayOutputStreamCharArrayReader / CharArrayWriter緩衝區作為流
字符串StringBufferInputStream (已棄用)StringReader / StringWriterString/Buffer 作為流
文件FileInputStream / FileOutputStreamFileReader / FileWriter磁盤文件讀寫
管道PipedInputStream / PipedOutputStreamPipedReader / PipedWriter線程間通信
序列SequenceInputStream—合併多個輸入流

轉換流 —— 橋接字節與字符

  • InputStreamReader:字節流 → 字符流 (指定 Charset)
  • OutputStreamWriter:字符流 → 字節流 (指定 Charset)

最佳實踐:永遠顯式指定編碼,如 new InputStreamReader(is, StandardCharsets.UTF_8),避免平台默認編碼導致亂碼。

裝飾者模式:處理流 (Filter Streams) 增強功能

核心思想:組合 > 繼承,動態為流添加緩衝、格式化、數據類型讀寫等能力。

經典組裝鏈

// 高效讀取文本文件 (按行)
BufferedReader in = new BufferedReader(
    new InputStreamReader(
        new FileInputStream("data.txt"), StandardCharsets.UTF_8));

// 高效寫入文本文件 (帶行號)
PrintWriter out = new PrintWriter(
    new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream("out.txt"), StandardCharsets.UTF_8)));

// 二進制數據持久化
DataOutputStream dos = new DataOutputStream(
    new BufferedOutputStream(
        new FileOutputStream("data.bin")));
dos.writeDouble(3.14159);
dos.writeUTF("Hello");

RandomAccessFile —— 隨機訪問文件

  • 模式:"r" (只讀)、"rw" (讀寫)、"rws"/"rwd" (同步)。
  • 核心方法:seek(long pos) 定位、readXXX()/writeXXX() 讀寫基本類型、getFilePointer() 獲取當前指針。
  • 適用場景:大文件斷點續傳、索引文件、嵌入式數據庫存儲引擎。

綜合實戰範例 (涵蓋讀寫、轉換、緩衝、格式化、隨機訪問)

import java.io.*;

public class IODemo {
    public static void main(String[] args) throws IOException {
        // 1. 按行讀取文件 → 字符串
        StringBuilder content = new StringBuilder();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream("input.txt"), "UTF-8"))) {
            String line;
            while ((line = br.readLine()) != null) content.append(line).append('\n');
        }

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

        // 3. 內存字節流 → DataInputStream 讀基本類型
        try (DataInputStream dis = new DataInputStream(
                new ByteArrayInputStream(content.toString().getBytes("UTF-8")))) {
            while (true) System.out.print((char)dis.readByte());
        } catch (EOFException ignored) { System.out.println("\n--- EOF ---"); }

        // 4. 格式化寫入文件 (帶行號)
        try (PrintWriter pw = new PrintWriter(
                new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8")))) {
            try (BufferedReader br = new BufferedReader(new StringReader(content.toString()))) {
                String line; int n = 1;
                while ((line = br.readLine()) != null) pw.println(n++ + ": " + line);
            }
        }

        // 5. 數據存儲與恢復 (DataOutput/InputStream)
        try (DataOutputStream dos = new DataOutputStream(
                new BufferedOutputStream(new FileOutputStream("data.bin")))) {
            dos.writeDouble(Math.PI);
            dos.writeUTF("\nThis was pi: writeUTF");
            dos.writeBytes("This was pi: writeBytes\n");
        }
        try (DataInputStream dis = new DataInputStream(
                new BufferedInputStream(new FileInputStream("data.bin")))) {
            System.out.println(dis.readDouble());
            System.out.println(dis.readUTF());
            System.out.println(dis.readUTF()); // readBytes 寫入的數據用 readUTF 讀會拋異常,此處僅示例
        }

        // 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);        // 覆蓋
            raf.seek(0);
            for (int i = 0; i < 10; i++) System.out.println("Value " + i + ": " + raf.readDouble());
        }
    }
}

現代替代方案 (JDK 7+)

  • NIO.2 (java.nio.file):Files.readAllLines(), Files.write(), Files.newBufferedReader(),API 更簡潔、支援符號鏈接、屬性讀取。
  • try-with-resources:自動關閉實現 AutoCloseable 的資源,消除 finally 樣板代碼。
  • StandardCharsets:StandardCharsets.UTF_8 替代字符串 "UTF-8",編譯期檢查拼寫。

總結

  1. 明確「字節 vs 字符」、「節點 vs 處理」二維分類,按需組裝流鏈。
  2. 緩衝 (Buffered*) 是效能基石,幾乎所有文件讀寫都應加緩衝。
  3. 轉換流 必須顯式指定 Charset,杜絕平台相關亂碼。
  4. 隨機訪問用 RandomAccessFile;現代項目優先考慮 NIO.2 FileChannel + MappedByteBuffer。
  5. 資源管理統一使用 try-with-resources,簡潔且安全。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
增強功能字節流裝飾者字符流裝飾者
緩衝 (提升效能)BufferedInputStream / BufferedOutputStreamBufferedReader / BufferedWriter
基本類型讀寫DataInputStream / DataOutputStream— (用 DataInput/OutputStream 配合轉換流)
行號追蹤LineNumberInputStream (棄用)LineNumberReader
回退/預讀PushbackInputStreamPushbackReader
格式化輸出PrintStreamPrintWriter