在Go 中,從API 端點解碼JSON 傳統上是透過將整個回應載入到記憶體中來完成的,如下所示在過去的方法中得到了證明。然而,處理大型 JSON 響應,尤其是那些包含顯著長度數組的響應,需要更有效率的方法。
為了避免記憶體過載,本文探討如何使用 Go 的 json.Decoder 及其事件驅動的解析功能來有效地處理 JSON 流。
json.Decoder 提供了一種解碼 JSON 資料的方法仍在流入,而不消耗整個流。這允許以零碎的方式處理大型 JSON 回應。
為了實作串流 JSON 解碼器,我們利用 Decoder.Token() 來擷取單一JSON 流中的標記。透過解釋這些標記,我們可以建立一個狀態機來追蹤我們在 JSON 結構中的位置。
考慮以下 JSON 結構:
{ "somefield": "value", "otherfield": "othervalue", "items": [ { "id": "1", "data": "data1" }, { "id": "2", "data": "data2" }, ... ] }
我們的目標是處理這個 JSON流,捕獲每個大物件(由“items”數組表示),而不需要解碼整個物件
dec := json.NewDecoder(res.Body) // or strings.NewReader(jsonStream) for demonstration purposes // Parse the outer JSON structure _, err := dec.Token() // Expecting an object if err != nil { ... } // Iterate over properties for dec.More() { prop, err := dec.Token().(string) // Property name if err != nil { ... } if prop != "items" { var v interface{} // Decode property value if err := dec.Decode(&v); err != nil { ... } log.Printf("Property '%s' = %v", prop, v) continue } // Parse items array _, err := dec.Token() // Expecting array if err != nil { ... } // Read and process items for dec.More() { lo := LargeObject{} // Initialize large object struct if err := dec.Decode(&lo); err != nil { ... } fmt.Printf("Item: %+v\n", lo) } _, err := dec.Token() // Expecting array closing if err != nil { ... } } // Parse outer object closing _, err := dec.Token() // Expecting object closing if err != nil { ... }
提供的範例將產生以下輸出,示範如何成功處理來自JSON 流的大物件:
Property 'somefield' = value Property 'otherfield' = othervalue Item: {Id:1 Data:data1} Item: {Id:2 Data:data2} ...
利用 json.Decoder 的事件驅動借助解析功能,開發人員可以高效處理大型 JSON 響應,避免內存過載並實現流數據的即時處理。所提出的實作可以作為在 Go 中實作此類解碼器的實用指南。
以上是Go 的 json.Decoder 如何有效率地對大型 JSON 回應進行串流解碼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!