處理大型 JSON 回應時,在解碼之前將整個回應載入記憶體並不理想。處理大型 JSON 有效負載時,使用 ioutil.ReadAll 函數可能會導致記憶體問題。本文將探討如何在 JSON 資料流入時進行動態解碼,避免記憶體消耗問題。
Go 標準庫中的 json.Decoder 提供了增量解析 JSON 流的能力。這是透過 Decoder.Token() 方法實現的。
Decoder.Token() 方法傳回 JSON 流中的下一個令牌,而不消耗它。這允許選擇性解析 JSON 資料和事件驅動處理。
事件驅動解析需要狀態機來追蹤 JSON 結構中的目前位置。我們可以使用此狀態機來處理流程中出現的 JSON 資料的不同部分。
例如,假設我們收到以下格式的JSON 回應:
{ "property1": "value1", "property2": "value2", "array": [ { "item1": "value3" }, { "item2": "value4" } ] }
我們可以寫一個函數來增量解析此JSON 流並單獨處理數組元素:
func processJSONStream(stream io.Reader) { decoder := json.NewDecoder(stream) state := "start" for decoder.More() { token, err := decoder.Token() if err != nil { log.Fatal(err) } switch state { case "start": if delim, ok := token.(json.Delim); ok && delim == '{' { state = "object" } else { log.Fatal("Expected object") } case "object": switch t := token.(type) { case json.Delim: if t == '}' { // End of object state = "end" } else if t == ',' { // Next property continue } else if t == '[' { // Array found state = "array" } if t == ':' { // Property value expected state = "prop_value" } case string: // Property name fmt.Printf("Property '%s'\n", t) default: // Property value fmt.Printf("Value: %v\n", t) } case "array": if delim, ok := token.(json.Delim); ok && delim == ']' { // End of array state = "object" } else if token == json.Delim('{') { // Array item object fmt.Printf("Item:\n") state = "item" } case "item": switch t := token.(type) { case json.Delim: if t == '}' { // End of item object fmt.Printf("\n") state = "array" } else if t == ',' { // Next item property fmt.Printf(",\n") continue } case string: // Item property name fmt.Printf("\t'%s'", t) default: // Item property value fmt.Printf(": %v", t) } case "prop_value": // Decode the property value var value interface{} if err := decoder.Decode(&value); err != nil { log.Fatal(err) } fmt.Printf("Value: %v\n", value) state = "object" } } }
當使用JSON 回應呼叫時,此函數會列印屬性名稱和值,以及陣列中的各個項目。
在事件驅動處理中使用json.Decoder 和Decoder.Token() 允許我們解析大數據JSON 增量響應,避免內存消耗問題,並在資料流入時實現高效處理。
以上是如何在 Go 中高效解碼大型串流 JSON?的詳細內容。更多資訊請關注PHP中文網其他相關文章!