Go处理大文件应采用流式处理,使用io.Copy实现高效边读边写,或用bufio.Scanner按行解析日志,避免OOM。

在 Go 中处理大文件时,直接读入内存会导致 OOM,正确做法是使用流式处理——边读边写,保持内存占用恒定。核心是利用 io.Copy 或带缓冲的 bufio 配合 os.File 的读写接口,避免一次性加载整个文件。
用 io.Copy 实现高效流式复制
io.Copy 是 Go 标准库中专为流式 I/O 设计的函数,内部自动使用 32KB 缓冲区,无需手动管理 buffer,适合大多数场景。
- 打开源文件(只读)和目标文件(可写,建议用
os.O_CREATE | os.O_WRONLY | os.O_TRUNC) - 直接调用
io.Copy(dst, src),它会持续从 src 读、向 dst 写,直到 EOF 或错误 - 操作完成后记得关闭两个文件句柄
示例:
dst, _ := os.Create("output.txt")src, _ := os.Open("input.log")
defer src.Close(); defer dst.Close()
io.Copy(dst, src) // 自动流式处理,内存友好
按行处理日志类文本(bufio.Scanner)
若需逐行解析(如过滤、转换、统计),bufio.Scanner 比 bufio.Reader.ReadLine 更安全简洁,且默认限制每行 64KB,防止单行过大爆内存。
立即学习“go语言免费学习笔记(深入)”;
- 用
bufio.NewScanner(file)包装文件对象 - 循环调用
scanner.Scan(),每次scanner.Text()返回当前行(不含换行符) - 对每行做业务逻辑,再写入目标文件或输出到其他 IO 接口
- 注意:若需处理超长行,可调
scanner.Buffer(make([]byte, 64*1024), 1
自定义缓冲读写(bufio.Reader/Writer)
当需要更精细控制(如跳过 BOM、校验、加解密、分块处理),可用 bufio.Reader 和 bufio.Writer 手动读写。
- 创建带缓冲的 reader/writer:
r := bufio.NewReaderSize(f, 64*1024),w := bufio.NewWriterSize(out, 32*1024) - 用
r.Read(p []byte)或r.ReadBytes('\n')等方式读取 - 写入后别忘了
w.Flush(),否则内容可能滞留在缓冲区 - 推荐设置缓冲大小为 4KB–64KB,太小增加系统调用开销,太大无益
错误处理与资源清理(关键!)
流式操作中,文件句柄、网络连接等资源必须显式释放,否则易泄漏。推荐用 defer + 明确 close,同时检查 close 错误(尤其写入后 close 可能触发磁盘 flush 错误)。
- 打开文件后立即 defer close,但注意 defer 在函数 return 后才执行,要确保顺序合理
- 写入完成后先
w.Flush(),再w.Close(),并检查两者错误 - 可封装工具函数统一处理 open/close/flush,减少重复代码
不复杂但容易忽略。










