【发布时间】:2015-08-06 14:04:05
【问题描述】:
我有一些要解析的大型 json 文件,并且我想避免一次将所有数据加载到内存中。我想要一个可以一次返回每个字符的函数/循环。
我发现 this example 用于迭代字符串中的单词,而 bufio 包中的 the ScanRunes 函数看起来一次可以返回一个字符。我也有来自 bufio 的 ReadRune 函数大部分都在工作,但这感觉是一种相当繁重的方法。
编辑
我比较了 3 种方法。所有人都使用循环从 bufio.Reader 或 bufio.Scanner 中提取内容。
- 在
bufio.Reader上使用.ReadRune循环读取符文。检查调用.ReadRune的错误。 - 在扫描仪上调用
.Split(bufio.ScanRunes)后从bufio.Scanner读取字节。在每次迭代中调用.Scan和.Bytes,检查.Scan调用是否有错误。 - 与 #2 相同,但从
bufio.Scanner读取文本,而不是使用.Text读取字节。我没有将一段符文与string([]runes)连接起来,而是将一段字符串与strings.Join([]strings, "")连接起来以形成最终的文本块。
在 23 MB json 文件上每次运行 10 次的时间是:
0.65 s2.40 s0.97 s
所以看起来ReadRune毕竟还不错。它还可以减少更详细的调用,因为每个符文都是在 1 次操作(.ReadRune)中获取的,而不是 2 次(.Scan 和 .Bytes)。
【问题讨论】:
-
为什么觉得它很重?我建议您试试看它是否适合您。
-
@AlexAtNet 每次手动调用该函数似乎是一种奇怪的方法,而不是使用某种内置迭代器(我认为这是
ScanRunes提供的)。此外,我必须将字符串转换为符文以检查字符序列,然后将符文转换回字符串以保存部分输出。看起来像我链接的第一个示例但与 bufio 一起使用的东西会更好。真正的答案是它闻起来很有趣——对于应该非常简单的东西来说有点太复杂了。 -
ReadRune 是逐个 rune 读取文件最方便的方法。要解析 JSON,您可以一次读取文件一个字节,因为所有语法都在 ASCII 范围内。
-
看我的回答。这很简单,我认为...
-
@BravadaZadada 关于所有 valid JSON 都在 ASCII 范围内并且能够逐字节读取的优点。我曾经担心的是使用 bufio 读取字节数组并意外切断了半个 utf-8 字符。显示我对编码的无知。 ://