ペイロード全体を読み取らずに JSON ストリームをデコードする
このシナリオでは、HTTP ストリーミング経由で受信した JSON データを、データをロードせずにデコードする必要があります。反応全体が記憶に残ります。目的は、個々の JSON 項目 (配列内の「ラージ オブジェクト」として表される) を処理し、受信したときにメッセージ キューにディスパッチすることです。
イベント駆動型 JSON 解析
これを実現するために、json.Decoder とその Decode() および Token() メソッドを使用します。 Decode() を使用すると単一の値をアンマーシャリングできますが、Token() を使用すると JSON ストリーム内の次のトークンのみを解析できるため、データを段階的に処理できます。
フライ トークンの処理
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 中国語 Web サイトの他の関連記事を参照してください。