BufferedReader 的 readLine() 自动识别 \n、\r、\r\n 并统一截断丢弃,返回不含换行符的字符串;空行返回"",末尾无换行符的行仍完整返回;相比 split("\n"),它避免漏识别跨平台换行符,实现归一化处理。

BufferedReader 的 readLine() 能自动识别并统一处理 \n、\r、\r\n 三种换行符,返回内容不含任何换行字符,无需按系统区分处理。
它怎么识别不同换行符
readLine() 内部会逐字节扫描输入流,一旦遇到以下任一序列即判定为行尾:
- \n(Unix/Linux/macOS 标准)
- \r(旧版 Mac,单独出现)
- \r\n(Windows 标准)
识别后立即截断,只把换行符之前的部分作为字符串返回,换行符本身被丢弃——所以你拿到的 line 永远不以 \n 或 \r 结尾。
空行和边界情况的处理表现
换行符差异不会影响语义判断,但会影响空行的返回值:
- 文件中只有 \r\n(Windows 空行)→ readLine() 返回 ""
- 文件末尾是 \r 且前面无内容 → 同样返回 ""
- 最后一行没换行符(如 Linux 下手动生成的文件)→ 该行仍完整返回,不会丢失
- 混合换行符(如 \r\n 后跟 \n)→ 每个换行符都独立触发一行,不会合并或跳过
为什么不用自己 split("\n")
手动用 String.split("\n") 会漏掉 \r 和 \r\n 场景,导致:
- Windows 文件在 Linux 环境下读取时,\r\n 被当做一个普通字符,整行连在下一行前
- 纯 \r 分隔的文本直接变成单行,完全无法分段
- 无法区分“空行”和“含\r的无效行”,逻辑易出错
而 readLine() 在底层已做归一化,上层代码只需关注业务逻辑,不必操心换行格式。
注意:兼容性 ≠ 保留原始换行信息
如果你需要知道某行原本是以 \r 还是 \r\n 结尾,或者要原样保留换行符写回文件,readLine() 就不适用了。它本质是“按行切分 + 清洗换行符”的工具。这种场景应改用:
- InputStream.read(byte[]) 配合手动解析
- 或 Java 11+ 的 String.lines()(返回 Stream,仍不带换行符,但更函数式)
但绝大多数日志分析、配置读取、CSV 解析等任务,readLine() 的跨平台清洗行为正是你想要的。

















