为了减少内存使用和减少延迟,我想在 json 对象全部发送之前开始处理在 http 响应中返回的对象。 我正在尝试在我的 Web 服务客户端上编写一个方法,该方法将查询返回一个 channel 的 Web 服务,该 channel 将在离开流时从 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(...)
method documentation 中列出的示例恰好显示了这一点。
简而言之,您执行以下步骤:
- 使用
dec.Token()
读取一个标记(并可选地期望它是一个左方括号) - 使用
dec.Decode()
读取 token ,同时使用dec.More()
- 可以选择阅读最后的右方括号。
例如 ( Go Playground ):
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: ]
关于json - 如何在不将整个数组加载到内存的情况下从包含 json 数组的流中一次读取一个 json 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52746987/