Menyahkod Strim JSON tanpa Membaca Keseluruhan Muatan
Dalam senario ini, kami menghadapi keperluan untuk menyahkod data JSON yang diterima melalui penstriman HTTP tanpa memuatkan keseluruhan tindak balas ke dalam ingatan. Objektifnya adalah untuk memproses item JSON individu (diwakili sebagai "objek besar" dalam tatasusunan) dan menghantarnya ke baris gilir mesej semasa ia diterima.
Penghuraian JSON Didorong Peristiwa
Untuk mencapai matlamat ini, kami menggunakan json.Decoder dan kaedah Decode() dan Token(). Decode() boleh digunakan untuk menyahmarshal satu nilai, manakala Token() membenarkan kami menghuraikan hanya token seterusnya dalam aliran JSON, membolehkan kami memproses data secara berperingkat.
On-the- Pemprosesan Token Terbang
Kami mewujudkan "mesin keadaan" untuk menjejaki kedudukan kami dalam struktur JSON. Dengan menganalisis setiap token, kami menavigasi melalui hierarki objek, mengenal pasti tatasusunan "item" dan elemen objeknya yang besar.
Pelaksanaan Kod
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") } }
Contoh Output
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}
Dengan menggunakan pendekatan penghuraian dipacu peristiwa ini, kami boleh memproses respons JSON yang besar dengan berkesan secara berperingkat, mengelakkan penggunaan memori yang berlebihan.
Atas ialah kandungan terperinci Bagaimana untuk Menyahkod Strim JSON dengan Cekap tanpa Memuatkan Keseluruhan Muatan ke dalam Memori?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!