推荐使用 bufferedreader 配合 files.newbufferedreader() 并结合 try-with-resources 逐行读取,明确指定 utf-8 编码,自动释放资源;超大文件可选 files.lines() 惰性流,但需避免全量收集。

Java 中按行读取大文本文件,核心是避免一次性加载整个文件到内存,推荐使用 BufferedReader 配合 Files.newBufferedReader(),兼顾性能、简洁性和资源安全。
用 try-with-resources + BufferedReader 逐行读取(推荐)
这是最常用、最稳妥的方式,自动关闭流,缓冲高效,适合 GB 级以下常规大文件:
- 使用
StandardCharsets.UTF_8明确指定编码,防止乱码 - 每行用
readLine()获取,返回null表示结束 - 无需手动
close(),try-with-resources 保证资源释放
<pre class="brush:php;toolbar:false;">Path path = Paths.get("huge-file.txt");
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
String line;
while ((line = reader.readLine()) != null) {
// 处理每一行,例如:System.out.println(line);
}
}
对超大文件(如几十 GB)做简单行计数或筛选时,考虑 Stream API
Java 8+ 的 Files.lines()
BufferedReader,适合函数式处理,但要注意:
- 必须用
try-with-resources 包裹,否则流未关闭会导致文件句柄泄漏 - 避免调用
collect(Collectors.toList())等全量收集操作,会吃光内存 - 适合
filter+limit或统计类场景
<pre class="brush:php;toolbar:false;">try (Stream<string> lines = Files.lines(path, StandardCharsets.UTF_8)) {
lines.limit(100).forEach(System.out::println);
}</string>
需要解析结构化大日志(如带时间戳、级别)?可配合正则或分隔符处理
单纯“按行”只是第一步;实际中常需拆解字段。建议在 readLine()
- 用
String.split()或Pattern.split()拆分,注意转义和性能 - 对固定格式(如 CSV),优先用专用库(如 OpenCSV)而非手写 split
- 避免在循环内重复编译正则表达式,提取为
static final Pattern
极端情况:内存极度受限或需跳过大量无效行?考虑自定义缓冲读取
标准 BufferedReader 默认 8KB 缓冲区已足够。仅当遇到特殊需求(如跳过前 N MB 二进制头、按自定义分隔符断行)才需底层操作:
- 用
FileChannel+ByteBuffer手动读块,自行查找换行符(\n或\r\n) - 复杂度高、易出错,一般项目不建议自行实现
- 优先评估是否真有必要——多数“大文件”问题本质是处理逻辑低效,而非读取本身
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











