json - 如何从包含 json 数组的流中一次读取一个 json 对象而不将整个数组加载到内存中?
问题描述
为了减少内存使用并减少延迟,我想在它们全部发送之前开始处理在 http 响应中返回的 json 对象。我正在尝试在我的 Web 服务客户端上编写一个方法,该方法将查询返回一个通道的 Web 服务,该通道将从 Web 请求中提供结构作为脱离流。
func (c *Client) GetMyObj() (<-chan models.MyObj, <-chan error) {
outChan := make(chan models.MyObj)
errChan := make(chan error)
go func() {
resp, err := httpClient.Get(c.ServiceUrl, "text/plain;charset=UTF-8", nil)
if err != nil {
errChan <- err
return
}
if resp.Status != "200 OK" {
errChan <- fmt.Errorf("http error: %1", resp.Status)
return
}
dec := json.NewDecoder(resp.Body)
for dec.More() {
myO:= models.MyObj{}
err := dec.Decode(&MyO)
if err != nil {
errChan <- err
return
}
outChan <- dfe
}
}()
return outChan, errChan
}
不幸的是,当它读取前面的左方括号时会产生异常。 json 文档看起来如下所示,但数组中有更多对象,对象上有更多属性,但你明白了:
[{"name":"Value"}
,{"name":"Value"}
,{"name":"Value"}]
解决方案
json.Decoder.Decode(...)
方法文档中列出的示例正好说明了这一点。
简而言之,您执行以下步骤:
dec.Token()
使用(并且可选地期望它是一个开放的方括号)读取一个标记dec.Decode()
使用while读取令牌dec.More()
- 或者,阅读最后的右方括号。
例如(去游乐场):
dec := json.NewDecoder(jsonStream)
type Item struct{ Name string }
// Read the open bracket.
t, err := dec.Token()
if err != nil {
panic(err)
}
fmt.Printf("OK: %T: %v\n", t, t)
// While the array contains values.
for dec.More() {
// Decode an array value.
var item Item
err := dec.Decode(&item)
if err != nil {
panic(err)
}
fmt.Printf("OK: item=%#v\n", item)
}
// Read the closing bracket.
t, err = dec.Token()
if err != nil {
panic(err)
}
fmt.Printf("OK: %T: %v\n", t, t)
// OK: json.Delim: [
// OK: item=main.Item{Name:"Value1"}
// OK: item=main.Item{Name:"Value2"}
// OK: item=main.Item{Name:"Value3"}
// OK: json.Delim: ]
推荐阅读
- virtual-machine - 在虚拟化环境中运行 RPA UI 交互
- internet-explorer-11 - 创建工作的基本示例聚合物 3 ie11
- dart - Stack inside Stack in flutter
- java - 将 concat 与 int 一起使用?(爪哇)
- python - python xarray刻度标签大小问题
- docker - 如何配置 docker 日志记录以有条件地发送到 CloudWatch?
- tfs - 成功构建后自动在 TFS 中合并已批准的 PR
- angular - Socket.io 和 Angular 使用异步管道
- html - 在 Angular 中,不会为 Angular mat-option 调用 onSelectionChange
- python - 如何通过 dev_appserver.py 在 Google App Engine 上使用 BeautifulSoup 和 lxml