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

Java IO 進階:readLine 原理、自定義 BufferedReader 與裝飾器模式實戰(畢向東 Day19 04-06)

     編輯:Java 相關知識

一、readLine() 底層原理

BufferedReader.readLine() 無論讀一行還是多字符,底層最終都調用 read() 逐字符從磁盤讀取,在內存中拼裝成行。核心邏輯:

  1. 循環調用 read() 獲取單字符 int ch。
  2. 遇到 '\r' 忽略;遇到 '\n' 返回已拼裝字符串。
  3. 流結束(-1)且緩衝區有內容 → 返回內容;否則返回 null。

二、手寫 MyBufferedReader 復刻 readLine

public class MyBufferedReader {
    private final Reader in;

    public MyBufferedReader(Reader in) { this.in = in; }

    public String myReadLine() throws IOException {
        StringBuilder sb = new StringBuilder();
        int ch;
        while ((ch = in.read()) != -1) {
            if (ch == '\r') continue;           // 忽略 CR
            if (ch == '\n') return sb.toString(); // 遇到 LF 返回行
            sb.append((char) ch);
        }
        return sb.length() > 0 ? sb.toString() : null; // 文件末尾無換行符
    }

    public void myClose() throws IOException { in.close(); }
}

// 測試
public static void main(String[] args) throws IOException {
    try (MyBufferedReader br = new MyBufferedReader(new FileReader("buf.txt"))) {
        String line;
        while ((line = br.myReadLine()) != null) System.out.println(line);
    }
}

三、裝飾器模式在 IO 體系中的應用

定義

當想增強現有對象功能時,定義裝飾類持有被裝飾對象引用,委託核心邏輯並在前後添加增強行為。

IO 中的經典結構

// 節點流(被裝飾者)
FileInputStream fis = new FileInputStream("a.txt");
// 處理流(裝飾者)層層包裹
BufferedInputStream bis = new BufferedInputStream(fis); // 增加緩衝
DataInputStream dis = new DataInputStream(bis);         // 增加基本類型讀取
// 使用
int i = dis.readInt();

優勢

  • 職責單一:每個流只關注一項功能(緩衝、轉碼、數據類型讀取)。
  • 靈活組合:運行時動態決定功能組合,避免繼承爆炸。
  • 符合開閉原則:新增功能只需新增裝飾類,不修改現有代碼。

四、自定義裝飾器示例:統計讀取字節數

public class CountingInputStream extends InputStream {
    private final InputStream in;
    private long count = 0;

    public CountingInputStream(InputStream in) { this.in = in; }

    @Override public int read() throws IOException {
        int b = in.read();
        if (b != -1) count++;
        return b;
    }
    @Override public int read(byte[] b, int off, int len) throws IOException {
        int n = in.read(b, off, len);
        if (n > 0) count += n;
        return n;
    }
    public long getCount() { return count; }
}

// 使用
try (CountingInputStream cis = new CountingInputStream(new FileInputStream("big.dat"))) {
    cis.readAllBytes();
    System.out.println("總讀取字節: " + cis.getCount());
}

五、總結

  1. readLine() 本質是循環 read() + 緩衝拼裝,理解此原理可自定義行讀取邏輯(如自定義分隔符)。
  2. 裝飾器模式是 Java IO 體系靈活性的核心,掌握其結構有助於設計可擴展的流處理鏈路。
  3. 實際開發中優先使用 BufferedReader/BufferedInputStream 等標準裝飾器,僅在有特殊統計、過濾、轉換需求時自定義裝飾類。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved