Maison > développement back-end > Golang > le corps du texte

Comment pouvons-nous encoder de gros flux de données en JSON sans charger d'objets en mémoire ?

Susan Sarandon
Libérer: 2024-10-28 04:08:30
original
273 Les gens l'ont consulté

 How Can We Encode Large Data Streams in JSON Without Loading Objects in Memory?

Encodage de flux de données volumineux en JSON sans chargement d'objets en mémoire

Dans les scénarios impliquant des flux de données étendus, le json Le package peut rencontrer des limitations lors de la tentative d'encodage simultané de tous les objets en mémoire. Considérez ce scénario :

<code class="go">type T struct {
    Foo string

    // Bar represents a large stream of objects
    // that we don't want to load entirely into memory.
    Bar chan string
}</code>
Copier après la connexion

Lors de la tentative de marshal t à l'aide de json.Encoder, une erreur se produit en raison de la chaîne de type chan non prise en charge.

<code class="go">if err := json.NewEncoder(os.Stdout).Encode(&t); err != nil {
    log.Fatal(err)
}</code>
Copier après la connexion

Dans des situations comme celles-ci, construire manuellement la chaîne JSON devient nécessaire. Cependant, un mécanisme plus efficace est souhaitable.

Si l'interface json.Marshaler ressemblait à cette structure, le processus d'encodage serait plus simple :

<code class="go">type Marshaler interface {
    MarshalJSON(io.Writer) error
}</code>
Copier après la connexion

Malheureusement, le package encoding/json actuellement il lui manque un tel mécanisme. Par conséquent, la personnalisation du package intégré peut être nécessaire. Pour y parvenir, des modifications de la fonction reflexValueQuoted dans encoding/json/encode.go sont nécessaires. Plus précisément, l'accent doit être mis sur le cas Array (avec repli sur Slice) et l'ajout d'un cas pour les canaux.

<code class="go">// Case Array:
e.WriteByte('[')
n := v.Len()
for i := 0; i < n; i++ {
    if i > 0 {
        e.WriteByte(',')
    }
    e.reflectValue(v.Index(i))
}
e.WriteByte(']')

// Case Chan:
e.WriteByte('[')
i := 0
for {
    x, ok := v.Recv()
    if !ok {
        break
    }
    if i > 0 {
        e.WriteByte(',')
    }
    e.reflectValue(x)
    i++
}
e.WriteByte(']')</code>
Copier après la connexion

Remarque : Le cas du canal peut nécessiter des vérifications supplémentaires qui ne sont pas évidents dans le code ci-dessus.

En implémentant ces modifications, les canaux seraient traités de la même manière que les tableaux dans le processus d'encodage. Cette modification pourrait être soumise sous forme de correctif au package encoding/json pour une éventuelle inclusion.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal