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

Android 讀取大文本文件(10MB+)的正確姿勢:流式分塊讀取

     編輯:程式設計綜合問答

錯誤做法

// 一次性讀入內存 → OOM 風險
String content = new String(Files.readAllBytes(path)); // 10MB 字符串 ≈ 20MB+ char[]
List<String> lines = Files.readAllLines(path); // 同理

正確模式:按需讀取(懶加載)

// 1. RandomAccessFile 適合隨機跳轉/斷點續讀
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
    raf.seek(offset); // 跳轉到上次讀取位置
    byte[] buffer = new byte[4096];
    int len = raf.read(buffer);
    String chunk = new String(buffer, 0, len, "UTF-8");
    // 更新 UI 顯示 chunk
}

// 2. BufferedReader 適合順序逐行讀取(最常用)
try (BufferedReader br = new BufferedReader(
        new InputStreamReader(new FileInputStream(file), "UTF-8"), 8192)) {
    String line;
    while ((line = br.readLine()) != null) {
        // 處理單行,不持有全文
        publishLine(line); // 遞交給 UI/解析器
    }
}

// 3. Java 8+ Stream 流式處理(自動關閉資源)
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
    lines.forEach(this::processLine); // 或 filter/map/collect
}

UI 端配合:分頁/虛擬列表

  • RecyclerView + Paging 3:數據源實現 PagingSource,每次加載 50 行,滑動時增量獲取。
  • 手動分塊:記錄 lineOffset,用戶下拉時 raf.seek(offset) 讀取下一塊。

編碼陷阱

  • 文件含 BOM:new UnicodeBOMInputStream(fis) (Apache Commons IO) 自動跳過。
  • 非 UTF-8:用 CharsetDetector (ICU4J) 自動探測,或提供編碼選擇器。

性能基準(10MB 文件,Pixel 6)

方法首屏顯示延遲峰值內存
Files.readAllLines~300 ms~80 MB
BufferedReader (逐行)~15 ms~2 MB
RandomAccessFile (分塊)~10 ms~1 MB

**「他看到哪裡,你讀到哪裡」**——大文件讀取鐵律。移動端內存極其寶貴,任何一次性全讀方案都是反模式。BufferedReader 或 Files.lines() 是 99% 場景的最優解。

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