如何在 Go 中逐行读取文件内容

2次阅读

如何在 Go 中逐行读取文件内容

本文详解 go 语言中使用 bufio.scanner 安全、高效地逐行读取文件的标准实践,涵盖基础用法、错误处理、内存注意事项及常见陷阱规避方法。

本文详解 go 语言中使用 bufio.scanner 安全、高效地逐行读取文件的标准实践,涵盖基础用法、错误处理、内存注意事项及常见陷阱规避方法。

在 Go 中实现“逐行读取文件”这一经典操作,并非依赖循环判断 EOF(Go 不提供显式 EOF 检测接口),而是通过 bufio.Scanner 的流式扫描机制完成——它自动按行分割、缓冲输入,并在每次调用 Scan() 时返回是否成功读取下一行。这是官方推荐、简洁且内存友好的方式。

以下是最小可行示例:

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():Scan() 返回 false 可能因到达文件末尾(正常)或发生错误(异常),仅靠循环退出无法区分;遗漏此检查将掩盖 I/O 故障。
  • 避免忽略 os.Open 错误:示例中已补全错误处理与 defer file.Close(),生产代码严禁使用 _ 忽略错误或忘记关闭文件。
  • 默认行长度限制为 64KB:若需读取超长行(如日志中的跟踪),应预先调用 scanner.Buffer(make([]byte, 64*1024), 1
  • Text() 返回的字符串生命周期仅在下次 Scan() 前有效:若需长期保存某行内容,请显式 line := String(append([]byte(nil), scanner.Bytes()…)) 或直接复制字节切片

总结:Go 的逐行读取不是“手动 while + EOF”,而是基于 bufio.Scanner 的声明式迭代。它兼顾性能、安全与可维护性——正确处理错误、及时释放资源、合理配置缓冲,即可稳健应对绝大多数文本处理场景。

text=ZqhQzanResources