大規模な JSON ペイロードを扱う場合、メモリ内のストリーム全体をデコードするのは非効率的で非現実的になる可能性があります。この記事では、json.Decoder を使用して、ストリーミングされる JSON をデコードする別のアプローチを検討します。
json.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 中国語 Web サイトの他の関連記事を参照してください。