目 录CONTENT

文章目录
Go

go 逐行读取超大文本文件

过客
2025-12-21 / 0 评论 / 0 点赞 / 2 阅读 / 0 字

在内存有限的设备上,需要读取大文本文件时,可以使用逐行读取方式来处理。

一、使用 bufio.Scanner

在 Go 语言中,逐行读取文本文件最高效、内存友好的方式是使用 bufio.Scanner。它适用于绝大多数场景(包括大文件),且代码简洁。

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
	file, err := os.Open("data.txt")
	if err != nil {
		log.Fatal(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 {
		log.Fatal(err)
	}
}

说明

  • scanner.Scan():每次读取一行,返回 true 表示还有下一行。
  • scanner.Text():返回当前行的字符串(自动去除 \n\r\n)。
  • 自动处理不同平台的换行符(\n, \r\n)。
  • 内存效率高​:不会一次性加载整个文件到内存,适合 GB 级大文件。

注意事项

超长行限制bufio.Scanner 默认最大行长度为 ​64KB​。如果某行超过这个长度,会报错:

bufio.Scanner: token too long

解决方法​:修改buf最大长度。

scanner := bufio.NewScanner(file)
const maxCapacity = 1024 * 1024 // 1MB
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)

for scanner.Scan() {
    line := scanner.Text()
    // ...
}

二、使用bufio.Reader(更底层,支持任意长度)

reader := bufio.NewReader(file)
for {
	line, err := reader.ReadString('\n')
	if err != nil {
		if err == io.EOF {
			if len(line) > 0 {
				// 处理最后一行(无换行符)
				fmt.Print(line)
			}
			break
		}
		log.Fatal(err)
	}
	fmt.Print(line) // 注意:line 包含 '\n'
}

适用于需要精确控制或处理超长行的场景。

总结

方法 优点 缺点 适用场景
bufio.Scanner 简洁、高效、自动去换行 默认行长 ≤ 64KB 绝大多数情况(推荐)
bufio.Reader 支持任意行长 代码稍复杂,需手动处理 EOF 和换行符 超长行、特殊格式
0
Go
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区