处理大型 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中文网其他相关文章!