本文演示如何在 Java 中高效讀取大文件,屬於 Baeldung「Java——回歸基礎」系列教程。核心目標:不將整個文件載入內存,而是逐行流式處理。
標準方式使用 Guava 或 Apache Commons IO 一次性讀取所有行:
Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path));
問題:所有行存入內存,文件過大時拋出 OutOfMemoryError。實測讀取 1GB 文件:
顯而易見,無論內存多大,一次性載入終將耗盡資源。且通常無需保留所有行,只需逐行處理後丟棄。
FileInputStream inputStream = null;
Scanner sc = null;
try {
inputStream = new FileInputStream(path);
sc = new Scanner(inputStream, "UTF-8");
while (sc.hasNextLine()) {
String line = sc.nextLine();
// 處理每一行
}
if (sc.ioException() != null) throw sc.ioException();
} finally {
if (inputStream != null) inputStream.close();
if (sc != null) sc.close();
}
效果:遍歷所有行,不保持引用,內存佔用穩定在 ~150MB(Total 763MB,Free 605MB)。
LineIterator it = FileUtils.lineIterator(theFile, "UTF-8");
try {
while (it.hasNext()) {
String line = it.nextLine();
// 處理每一行
}
} finally {
LineIterator.closeQuietly(it);
}
效果:同樣不將整文件載入內存,佔用 ~150MB(Total 752MB,Free 564MB)。
流式逐行處理是大文件讀取的正確姿勢:
OutOfMemoryError完整代碼可在 GitHub 專案獲取(基於 Eclipse,易導入運行)。