// 一次性讀入內存 → 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
}
PagingSource,每次加載 50 行,滑動時增量獲取。lineOffset,用戶下拉時 raf.seek(offset) 讀取下一塊。new UnicodeBOMInputStream(fis) (Apache Commons IO) 自動跳過。CharsetDetector (ICU4J) 自動探測,或提供編碼選擇器。| 方法 | 首屏顯示延遲 | 峰值內存 |
|---|---|---|
Files.readAllLines | ~300 ms | ~80 MB |
BufferedReader (逐行) | ~15 ms | ~2 MB |
RandomAccessFile (分塊) | ~10 ms | ~1 MB |
**「他看到哪裡,你讀到哪裡」**——大文件讀取鐵律。移動端內存極其寶貴,任何一次性全讀方案都是反模式。
BufferedReader或Files.lines()是 99% 場景的最優解。