使用 MarshalJSON 编码大数据流而不加载内存中的所有对象
想要使用 json.Encoder 编码大数据流而不加载一次将所有内容全部存入内存是一个常见问题。不幸的是,encoding/json 包不提供对此的直接支持。
当前解决方法
正如您提到的,当前的解决方案是手动构建 JSON 字符串你自己。这涉及到当数据从流中可用时,逐段编写 JSON 结构。这是一种有效的方法,但可能很乏味且容易出错。
建议的补丁
要改进此过程,可以修改encoding/json 包。具体来说,可以修改encoding/json/encode.go 中的reflectValueQuoted 函数来处理数组等通道。这将使数据从通道直接流式传输到 JSON 输出。
以下是对 ReflectValueQuoted 中数组情况的建议更改:
<code class="go">case reflect.Array: e.WriteByte('[') n := v.Len() for i := 0; i < n; i++ { if i > 0 { e.WriteByte(',') } e.reflectValue(v.Index(i)) } e.WriteByte(']') // Add the following case for channels: case reflect.Chan: e.WriteByte('[') i := 0 for { x, ok := v.Recv() if !ok { break } if i > 0 { e.WriteByte(',') } e.reflectValue(x) i++ } e.WriteByte(']')</code>
补丁的好处
此补丁将使对大数据流进行编码变得更加容易,而无需将所有对象加载到内存中。它还将消除手动字符串连接的需要,降低错误风险并提高代码可读性。
结论
尽管建议的补丁不是当前补丁的一部分coding/json 包,它展示了一种潜在的改进,可以使流式 JSON 数据更加高效和方便。
以上是我们如何将大数据流式传输为 JSON,而不将所有对象加载到内存中?的详细内容。更多信息请关注PHP中文网其他相关文章!