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

深度解析 Java IO 系統架構與核心類別

     編輯:Java 相關知識

Java IO 系統是處理資料輸入輸出的基礎設施,理解其架構對編寫高效、健壯的 IO 程式碼至關重要。本文系統梳理流的分類、裝飾器模式應用、RandomAccessFile 特性,並附完整範例程式碼。

一、流的兩大體系

Java 中所有流均繼承自四大抽象基類:InputStream、OutputStream(位元組流)、Reader、Writer(字元流)。

1. 位元組導向流

以位元組(8 bits)為單位讀寫,適用於二進位資料(圖片、聲音、序列化物件等)。

輸入流用途
ByteArrayInputStream將記憶體緩衝區作為輸入來源
StringBufferInputStream將 String 物件作為輸入來源(已過時)
FileInputStream讀取檔案
PipedInputStream執行緒間管道通訊
SequenceInputStream合併多個輸入流
輸出流用途
ByteArrayOutputStream寫入記憶體緩衝區
FileOutputStream寫入檔案
PipedOutputStream執行緒間管道通訊
SequenceOutputStream合併多個輸出流

2. 字元導向流

以 Unicode 字元(16 bits)為單位,專為文字資料設計,內部自動處理編碼轉換。

讀取器對應位元組流
CharArrayReaderByteArrayInputStream
StringReaderStringBufferInputStream
FileReaderFileInputStream
PipedReaderPipedInputStream
寫入器對應位元組流
CharArrayWriterByteArrayOutputStream
StringWriter(無直接對應)
FileWriterFileOutputStream
PipedWriterPipedOutputStream

兩者轉換橋樑

  • InputStreamReader:位元組輸入流 → 字元讀取器
  • OutputStreamWriter:位元組輸出流 → 字元寫入器

二、裝飾器模式:為流動態添加功能

FilterInputStream / FilterOutputStream 及其子類實現裝飾器模式,無需修改原始流即可增強功能。

常用裝飾類別

類別功能適用流類型
BufferedInputStream / BufferedReader緩衝讀取,提升效能位元組 / 字元
DataInputStream / DataOutputStream讀寫基本型別位元組
LineNumberInputStream / LineNumberReader追蹤行號位元組 / 字元
PushbackInputStream / PushbackReader回推資料,用於編譯器位元組 / 字元
PrintStream / PrintWriter格式化輸出位元組 / 字元

實戰場景:若需「先緩存再寫入檔案」,只需將 FileOutputStream 包裝為 BufferedOutputStream,再包裝為 DataOutputStream 即可同時獲得緩衝與基本型別寫入能力。

三、RandomAccessFile:隨機存取檔案

  • 單一類別同時支援讀寫,構造時指定模式:"r"(唯讀)、"rw"(讀寫)
  • 內部維護檔案指標,可任意 seek(long pos) 跳轉
  • 適合需隨機讀寫的場景(如資料庫索引、大檔案斷點續傳)

四、綜合應用範例

import java.io.*;

public class IODemo {
    public static void main(String[] args) throws IOException {
        // 1. 緩衝逐行讀取檔案
        StringBuilder content = new StringBuilder();
        try (BufferedReader in = new BufferedReader(new FileReader("TestIO.java"))) {
            String line;
            while ((line = in.readLine()) != null) content.append(line).append("\n");
        }

        // 2. 從標準輸入讀取
        try (BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in))) {
            System.out.println("Enter a line:");
            System.out.println(stdin.readLine());
        }

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

        // 4. 格式化寫入檔案
        try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("TestIO.out")))) {
            try (BufferedReader br = new BufferedReader(new StringReader(content.toString()))) {
                String line; int lineNo = 1;
                while ((line = br.readLine()) != null) out.println(lineNo++ + ":" + line);
            }
        }

        // 5. 基本型別序列化與反序列化
        try (DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("Data.txt")))) {
            dos.writeDouble(Math.PI);
            dos.writeChars("Pi via writeChars\n");
            dos.writeBytes("Pi via writeBytes\n");
        }
        try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("Data.txt")))) {
            System.out.println(dis.readDouble());
            try (BufferedReader br = new BufferedReader(new InputStreamReader(dis))) {
                System.out.println(br.readLine());
                System.out.println(br.readLine());
            }
        }

        // 6. RandomAccessFile 隨機存取
        try (RandomAccessFile raf = new RandomAccessFile("rtest.dat", "rw")) {
            for (int i = 0; i < 10; i++) raf.writeDouble(i * 1.414);
        }
        try (RandomAccessFile raf = new RandomAccessFile("rtest.dat", "r")) {
            for (int i = 0; i < 10; i++) System.out.println("Value " + i + ":" + raf.readDouble());
        }
        try (RandomAccessFile raf = new RandomAccessFile("rtest.dat", "rw")) {
            raf.seek(5 * 8);  // 定位第 6 個 double
            raf.writeDouble(47.0001);
        }
    }
}

關鍵點總結

  1. 根據資料性質選擇位元組流或字元流
  2. 善用緩衝流(Buffered*)大幅提升 IO 效能
  3. 裝飾器鏈順序影響功能組合,通常:節點流 → 緩衝流 → 功能流
  4. RandomAccessFile 獨立於四大流體系,提供隨機存取能力
  5. Java 7+ 建議使用 try-with-resources 自動關閉資源
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved