json - 如何在不将整个数组加载到内存的情况下从包含 json 数组的流中一次读取一个 json 对象?

标签 json go stream

为了减少内存使用和减少延迟,我想在 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 中列出的示例恰好显示了这一点。

简而言之,您执行以下步骤:

  1. 使用 dec.Token() 读取一个标记(并可选地期望它是一个左方括号)
  2. 使用 dec.Decode() 读取 token ,同时使用 dec.More()
  3. 可以选择阅读最后的右方括号。

例如 ( 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/

相关文章:

javascript - 如何从 fetch api 保存到状态并保存到局部变量结果

python - 使用 google-cloud-python 从 BigQuery 以 JSON 格式获取结果

php - 这个 json 可能在 jquery 中输出为数组吗?

javascript - 如何从 Kaizala API 获取 accessToken

sql - 如何在遍历行时修改行

go - 在 golang pprof 中显示函数调用次数

json - Golang json解析

python - 从 StringIO 读取直到遇到某个字节的快速方法

java - 尝试在 Java 中的数组上使用 .stream() 时出现“找不到符号错误”

java - Scala 对象列表到逗号分隔的字符串