
本文详解如何在go中高效、安全地逐行读取文本文件,涵盖标准库bufio.scanner的核心用法、常见陷阱、错误处理及性能优化建议。
本文详解如何在go中高效、安全地逐行读取文本文件,涵盖标准库bufio.scanner的核心用法、常见陷阱、错误处理及性能优化建议。
在Go语言中,“逐行读取文件”并非通过传统C风格的while (!EOF)循环实现,而是依托bufio.Scanner这一专为分词(包括按行切分)设计的高效、内存友好的工具。它内部自动处理缓冲、换行符识别(支持\n、\r\n)和边界情况,是官方推荐的标准做法。
以下是最简洁可靠的逐行读取示例:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.Open("path/to_file")
if err != nil {
panic(fmt.Sprintf("无法打开文件: %v", err))
}
defer file.Close() // 关键:务必关闭文件句柄
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text() // 获取当前行(不含换行符)
fmt.Println(line)
}
// 检查扫描过程中是否发生错误(如I/O错误)
if err := scanner.Err(); err != nil {
panic(fmt.Sprintf("读取文件时出错: %v", err))
}
}✅ 关键要点说明:
- 必须显式检查 scanner.Err():scanner.Scan() 仅返回bool表示是否成功读到下一行,但不暴露底层I/O错误;忽略此检查可能导致静默失败。
- 务必调用 file.Close():使用defer确保资源及时释放,避免文件描述符泄漏。
- scanner.Text() 返回无换行符字符串:若需保留原始换行符,可改用 scanner.Bytes() 并手动追加(如 append(lineBytes, '\n'))。
⚠️ 注意事项与进阶建议:
立即学习“go语言免费学习笔记(深入)”;
-
超长行处理:默认情况下,Scanner 单行上限为 64KB。若需读取超长行(如日志或JSON行),应预先设置缓冲区:
scanner.Buffer(make([]byte, 0, 1024*1024), 1024*1024) // 支持最大1MB行
-
替代方案对比:
- bufio.Reader.ReadString('\n') 更底层、更灵活(可自定义分隔符),但需手动处理io.EOF和错误;
- bytes.Split(bytes, []byte{'\n'}) 适用于小文件内存加载场景,不适用于大文件流式处理。
- 编码兼容性:bufio.Scanner 原生只处理UTF-8字节流。若需读取GBK、UTF-16等编码,需先用golang.org/x/text/encoding包解码后再扫描。
总之,bufio.Scanner 是Go中逐行读取文件的首选方案——它兼顾简洁性、安全性与性能。掌握其正确用法(尤其错误检查与资源管理),是编写健壮Go I/O程序的基础能力。










