在不讀取整個有效負載的情況下解碼JSON 流
在這種情況下,我們需要解碼透過HTTP 流接收的JSON 資料而不載入整個反應進入記憶。目標是處理單一 JSON 項(在陣列中表示為「大物件」),並在收到它們時將它們分派到訊息佇列。
事件驅動的 JSON 解析
為了實現這一點,我們使用 json.Decoder 及其 Decode() 和 Token() 方法。 Decode() 可用於解組單一值,而 Token() 允許我們僅解析 JSON 流中的下一個標記,使我們能夠增量處理資料。
On-the- Fly 令牌處理
我們建立一個「狀態機」來追蹤我們在 JSON 結構中的位置。透過分析每個標記,我們瀏覽物件層次結構,識別「items」陣列及其大物件元素。
程式碼實作
package main import ( "bufio" "encoding/json" "fmt" "io" "log" "os" ) // Helper error handler func he(err error) { if err != nil { log.Fatal(err) } } // Large object struct type LargeObject struct { Id string `json:"id"` Data string `json:"data"` } func main() { // JSON input for demonstration in := `{"somefield": "value", "otherfield": "othervalue", "items": [ {"id": "1", "data": "data1"}, {"id": "2", "data": "data2"}, {"id": "3", "data": "data3"}, {"id": "4", "data": "data4"}]}` dec := json.NewDecoder(strings.NewReader(in)) // Expect an object t, err := dec.Token() he(err) if delim, ok := t.(json.Delim); !ok || delim != '{' { log.Fatal("Expected object") } // Read props for dec.More() { t, err = dec.Token() he(err) prop := t.(string) if t != "items" { var v interface{} he(dec.Decode(&v)) fmt.Printf("Property '%s' = %v\n", prop, v) continue } // It's the "items". Expect an array t, err = dec.Token() he(err) if delim, ok := t.(json.Delim); !ok || delim != '[' { log.Fatal("Expected array") } // Read items (large objects) for dec.More() { // Read next item (large object) 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") } }
範例輸出
Property 'somefield' = value Property 'otherfield' = othervalue Item: {Id:1 Data:data1} Item: {Id:2 Data:data2} Item: {Id:3 Data:data3} Item: {Id:4 Data:data4}
透過使用這種事件驅動的解析方法,我們可以有效地處理大的JSON 增量回應,避免過多的記憶體消耗。
以上是如何在不將整個負載載入到記憶體的情況下高效解碼 JSON 流?的詳細內容。更多資訊請關注PHP中文網其他相關文章!