我有一些要解析的大型json文件,我想避免一次将所有数据加载到内存中。我想要一个可以一次返回每个字符的函数/循环。
我发现this example用于遍历字符串中的单词,并且bufio包中的the ScanRunes函数看起来可以一次返回一个字符。我也有bufio的ReadRune
函数可以正常工作,但是感觉很沉重。
编辑
我比较了3种方法。全部使用循环从bufio.Reader或bufio.Scanner中提取内容。
.ReadRune
上的bufio.Reader
循环读取 rune 。检查从对.ReadRune
的调用是否有错误。 bufio.Scanner
后,从.Split(bufio.ScanRunes)
中读取字节。在每次迭代中分别调用.Scan
和 .Bytes
,检查.Scan
调用是否有错误。 bufio.Scanner
从.Text
而不是字节读取文本。我没有使用string([]runes)
来连接一小段 rune ,而是使用strings.Join([]strings, "")
来连接一串字符串,以形成最终的文本 Blob 。 在23 MB的json文件上运行10次的时间是:
0.65 s
2.40 s
0.97 s
所以
ReadRune
看起来还算不错。由于每个 rune 都是通过1次操作(.ReadRune
)而不是2次(.Scan
和.Bytes
)提取的,因此它也导致了较小的详细调用。 最佳答案
只需在循环中逐一读取每个 rune ... See example
package main
import (
"bufio"
"fmt"
"io"
"log"
"strings"
)
var text = `
The quick brown fox jumps over the lazy dog #1.
Быстрая коричневая лиса перепрыгнула через ленивую собаку.
`
func main() {
r := bufio.NewReader(strings.NewReader(text))
for {
if c, sz, err := r.ReadRune(); err != nil {
if err == io.EOF {
break
} else {
log.Fatal(err)
}
} else {
fmt.Printf("%q [%d]\n", string(c), sz)
}
}
}