處理大型 JSON 負載時,在內存中解碼整個流可能效率低下且不切實際。在本文中,我們探索一種使用 json.Decoder 來解碼 JSON 的替代方法。
json.Decoder 提供了Decoder .Token() 方法,它允許我們解析JSON 流中的下一個令牌,而無需消耗整個物件。這使得事件驅動的解析成為可能,我們可以增量地處理令牌並建立狀態機來追蹤 JSON 結構中的進度。
讓我們看一下實現解決問題中描述的特定場景:
import ( "encoding/json" "fmt" "log" ) type LargeObject struct { Id string `json:"id"` Data string `json:"data"` } // Helper error handler he := func(err error) { if err != nil { log.Fatal(err) } } // Parse and process a JSON object stream func ParseStream(reader io.Reader) { dec := json.NewDecoder(reader) // Expect an object t, err := dec.Token() he(err) if delim, ok := t.(json.Delim); !ok || delim != '{' { log.Fatal("Expected object") } // Read properties for dec.More() { t, err = dec.Token() he(err) prop := t.(string) if t != "items" { var v interface{} he(dec.Decode(&v)) log.Printf("Property '%s' = %v", prop, v) continue } // "items" array t, err := dec.Token() he(err) if delim, ok := t.(json.Delim); !ok || delim != '[' { log.Fatal("Expected array") } // Read large objects for dec.More() { lo := LargeObject{} he(dec.Decode(&lo)) fmt.Printf("Item: %+v\n", lo) } // Array closing delim t, err = dec.Token() he(err) if delim, ok := t.(json.Delim); !ok || delim != ']' { log.Fatal("Expected array closing") } } // Object closing delim t, err = dec.Token() he(err) if delim, ok := t.(json.Delim); !ok || delim != '}' { log.Fatal("Expected object closing") } }
此實現增量處理JSON 對象,解碼屬性和大對象分別地。 he() 函數用來處理致命退出的錯誤。
透過避免將整個 JSON 回應載入到記憶體中,這種方法可以有效處理大型負載。
以上是如何在 Go 中高效解碼大型 JSON 串流?的詳細內容。更多資訊請關注PHP中文網其他相關文章!