0

0

Go语言如何按行读取文件_bufio Scanner读取文本文件

P粉602998670

P粉602998670

发布时间:2026-01-14 12:56:02

|

154人浏览过

|

来源于php中文网

原创

Scanner 读到“空行”就停是因为行长度超限而非真遇到空行;默认缓冲区64KB,超长行触发bufio.ErrTooLong导致Scan()返回false;应检查scanner.Err()并用scanner.Buffer()扩大缓冲区。

go语言如何按行读取文件_bufio scanner读取文本文件

为什么 Scanner 读到空行就停了?

默认情况下 bufio.Scanner 的缓冲区上限是 64KB,遇到超长行(比如日志中混入的 base64 字段、单行 JSON)会直接返回 scanner.Err() == bufio.ErrTooLong,且后续调用 scanner.Scan() 返回 false,看起来像“卡在空行”或“提前结束”。这不是空行问题,而是行长度越界导致扫描器终止。

  • scanner.Err() 检查是否为 bufio.ErrTooLong,而不是只看 Scan() 返回值
  • 可通过 scanner.Buffer(make([]byte, 64*1024), 1 手动扩大缓冲区上限(第二个参数是最大令牌长度,设为 1MB)
  • 若文件含真正不可控的超长行,建议改用 bufio.Reader.ReadLine() 或逐字节读取

Scanner 默认按什么分隔符切行?

bufio.Scanner 默认使用 bufio.ScanLines 作为分隔函数,它识别 \n\r\n\r 三种换行符,并**自动剥离**这些换行符。注意:\r 单独出现时也会被当作行结束,这在处理旧 Mac 文件或某些串口输出时可能引发意外切分。

  • Windows 文件(\r\n)和 Unix 文件(\n)都能正确处理
  • 若需保留换行符,不能用 scanner.Text(),应改用 scanner.Bytes() 并自行追加(但要注意 Bytes() 返回的是内部缓冲区切片,下一次 Scan() 后失效)
  • 自定义分隔符可用 scanner.Split(),例如按空行分割:传入 bufio.ScanLines 改写逻辑,或直接用 bytes.Split 预处理

如何安全地边读边解析 CSV 或 JSON 行?

每行一个 JSON 对象(JSON Lines)或 CSV 记录时,不能假设 scanner.Text() 返回的字符串一定合法——网络传输截断、编码错误、BOM 头都可能导致解析失败。必须对每一行单独做错误隔离。

萝卜简历
萝卜简历

免费在线AI简历制作工具,帮助求职者轻松完成简历制作。

下载
  • 不要把所有行存进 slice 再批量解析;每调用一次 scanner.Scan() 就立即处理一行
  • json.Unmarshal([]byte(line), &v)if err != nil 判断,出错时打印 scanner.Bytes() 的原始字节(可 hex dump),方便定位乱码或截断位置
  • CSV 场景下,优先用 csv.NewReader(scanner) 替代手动 strings.Split(),它能正确处理带引号、换行、逗号的字段
file, _ := os.Open("data.jsonl")
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
    line := scanner.Bytes() // 避免 string 转换丢失二进制数据
    var record map[string]interface{}
    if err := json.Unmarshal(line, &record); err != nil {
        log.Printf("parse error at offset %d: %v, raw: %x", scanner.Bytes(), err)
        continue
    }
    // 处理 record
}

Scanner 和 ReadLine 哪个更适合大文件?

性能差异不大,但语义和错误处理完全不同:Scanner 是“按逻辑行”抽象,ReadLine() 是“按物理字节边界”读取。前者更易用,后者更可控。

立即学习go语言免费学习笔记(深入)”;

  • Scanner 自动跳过空白行(如果没禁用),而 ReadLine() 会把空行([]byte{})也返回
  • ReadLine() 遇到不完整行(末尾无换行符)时返回 isPrefix=true,需循环读取拼接;ScannerErrTooLong 时也要求你处理前缀,但逻辑更隐蔽
  • 若需精确控制内存(如流式解密后按行处理),ReadLine() 更合适,因为你能复用同一块 []byte 缓冲区
真正麻烦的是混合编码(UTF-8 + GBK)、行尾不统一、以及 Scanner 缓冲区复用机制带来的生命周期陷阱——scanner.Bytes() 不是新分配的内存,别把它塞进 goroutine 里异步用。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

411

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

532

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

309

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

Go中Type关键字的用法
Go中Type关键字的用法

Go中Type关键字的用法有定义新的类型别名或者创建新的结构体类型。本专题为大家提供Go相关的文章、下载、课程内容,供大家免费下载体验。

233

2023.09.06

go怎么实现链表
go怎么实现链表

go通过定义一个节点结构体、定义一个链表结构体、定义一些方法来操作链表、实现一个方法来删除链表中的一个节点和实现一个方法来打印链表中的所有节点的方法实现链表。

444

2023.09.25

go语言编程软件有哪些
go语言编程软件有哪些

go语言编程软件有Go编译器、Go开发环境、Go包管理器、Go测试框架、Go文档生成器、Go代码质量工具和Go性能分析工具等。本专题为大家提供go语言相关的文章、下载、课程内容,供大家免费下载体验。

246

2023.10.13

0基础如何学go语言
0基础如何学go语言

0基础学习Go语言需要分阶段进行,从基础知识到实践项目,逐步深入。php中文网给大家带来了go语言相关的教程以及文章,欢迎大家前来学习。

693

2023.10.26

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号