Maison >développement back-end >Golang >Comment décoder efficacement les flux JSON sans charger l'intégralité de la charge utile en mémoire ?
Décoder les flux JSON sans lire l'intégralité de la charge utile
Dans ce scénario, nous rencontrons la nécessité de décoder les données JSON reçues via le streaming HTTP sans charger le la réponse entière en mémoire. L'objectif est de traiter des éléments JSON individuels (représentés comme des « gros objets » dans un tableau) et de les envoyer vers une file d'attente de messages au fur et à mesure de leur réception.
Analyse JSON basée sur les événements
Pour y parvenir, nous utilisons le json.Decoder et ses méthodes Decode() et Token(). Decode() peut être utilisé pour désassembler une seule valeur, tandis que Token() nous permet d'analyser uniquement le jeton suivant dans le flux JSON, nous permettant ainsi de traiter les données de manière incrémentielle.
Sur le- Traitement des jetons Fly
Nous établissons une « machine à états » pour suivre notre position au sein de la structure JSON. En analysant chaque jeton, nous naviguons dans la hiérarchie des objets, en identifiant le tableau « éléments » et ses grands éléments d'objet.
Implémentation du code
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") } }
Exemple de sortie
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}
En utilisant cette approche d'analyse basée sur les événements, nous pouvons traiter efficacement les grandes réponses JSON progressivement, en évitant une consommation excessive de mémoire.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!