Golang中使用bufio.Scanner读取10GB大文件时遇到"token too long"错误
Golang中使用bufio.Scanner读取10GB大文件时遇到"token too long"错误 在读取一个10GB的大型文本文件时,每行都是长嵌套的JSON结构。 我使用以下代码读取内容:
scanner := bufio.NewScanner(file)
scanner.Scan()
遇到错误:bufio.Scanner: token too long
需要帮助解决此问题,或者提供替代的代码片段。
你能展示给我们看产生这个错误的代码行吗?
更多关于Golang中使用bufio.Scanner读取10GB大文件时遇到"token too long"错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
谢谢。我也做了同样的事情。 ☀️ 🤫
你可以尝试使用 bufio.NewReader(file) 然后调用 ReadString("/n")
bufio.NewReader(file)
ReadString("/n")
你好
使用 https://golang.org/pkg/bufio/#Scanner.Buffer 设置足够大的缓冲区用于读取。
感谢,但这种方式需要对代码进行更多修改,而不仅仅是更改缓冲区限制。

在Golang中使用bufio.Scanner读取大文件时遇到"token too long"错误是因为默认的缓冲区大小限制。bufio.Scanner的默认最大令牌大小为bufio.MaxScanTokenSize(64KB),当单行超过这个限制时就会报错。
以下是几种解决方案:
方案1:自定义缓冲区大小
package main
import (
"bufio"
"bytes"
"os"
)
func main() {
file, err := os.Open("large_file.json")
if err != nil {
panic(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
// 自定义缓冲区大小(例如10MB)
buf := make([]byte, 0, 64*1024)
scanner.Buffer(buf, 10*1024*1024) // 初始大小64KB,最大10MB
for scanner.Scan() {
line := scanner.Text()
// 处理每一行
_ = line
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
方案2:使用bufio.Reader逐块读取
package main
import (
"bufio"
"io"
"os"
)
func readLargeFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
reader := bufio.NewReader(file)
buf := make([]byte, 1024*1024) // 1MB缓冲区
for {
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
return err
}
if n == 0 {
break
}
// 处理读取的数据块
chunk := buf[:n]
_ = chunk
}
return nil
}
方案3:使用ioutil.ReadFile(适用于可装入内存的文件)
package main
import (
"io/ioutil"
"os"
)
func readEntireFile(filename string) error {
data, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
// 整个文件内容在data中
_ = data
return nil
}
方案4:逐字符读取处理JSON行
package main
import (
"bufio"
"io"
"os"
)
func readJSONLines(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
reader := bufio.NewReader(file)
var line []byte
for {
chunk, isPrefix, err := reader.ReadLine()
if err == io.EOF {
break
}
if err != nil {
return err
}
line = append(line, chunk...)
if !isPrefix {
// 完整的一行JSON
jsonLine := string(line)
_ = jsonLine
// 重置line
line = line[:0]
}
}
return nil
}
对于10GB的JSON文件,推荐使用方案1或方案2。方案1通过增加缓冲区大小来处理长行,方案2则提供了更细粒度的控制,适合处理超大型文件。根据你的JSON行平均长度选择合适的缓冲区大小。

