Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk Menyahkod JSON Penstriman Besar dengan Cekap dalam Go?

Bagaimana untuk Menyahkod JSON Penstriman Besar dengan Cekap dalam Go?

Mary-Kate Olsen
Mary-Kate Olsenasal
2025-01-02 20:03:40342semak imbas

How to Efficiently Decode Large Streaming JSON in Go?

Cara Menyahkod Penstriman JSON dalam Go

Apabila bekerja dengan respons JSON yang besar, adalah tidak sesuai untuk memuatkan keseluruhan respons ke dalam memori sebelum menyahkodnya. Menggunakan fungsi ioutil.ReadAll boleh menyebabkan masalah ingatan apabila berurusan dengan muatan JSON yang besar. Artikel ini akan meneroka cara untuk menyahkod data JSON dengan cepat semasa ia mengalir masuk, mengelakkan masalah penggunaan memori.

Penstriman JSON dengan json.Decoder

Json.Decoder dalam pustaka standard Go menyediakan keupayaan untuk menghuraikan aliran JSON secara berperingkat. Ini dicapai melalui kaedah Dekoder.Token().

Kaedah Dekoder.Token() mengembalikan token seterusnya dalam strim JSON tanpa menggunakannya. Ini membenarkan penghuraian terpilih bagi data JSON dan pemprosesan dipacu peristiwa.

Mengendalikan Struktur JSON

Penghuraian dipacu peristiwa memerlukan mesin keadaan untuk menjejak kedudukan semasa dalam struktur JSON. Kita boleh menggunakan mesin keadaan ini untuk memproses bahagian data JSON yang berbeza kerana ia muncul dalam strim.

Sebagai contoh, katakan kami menerima respons JSON dengan format berikut:

{
    "property1": "value1",
    "property2": "value2",
    "array": [
        { "item1": "value3" },
        { "item2": "value4" }
    ]
}

Kita boleh menulis fungsi yang menghuraikan aliran JSON ini secara berperingkat dan memproses elemen tatasusunan secara berasingan:

func processJSONStream(stream io.Reader) {
    decoder := json.NewDecoder(stream)

    state := "start"
    for decoder.More() {
        token, err := decoder.Token()
        if err != nil {
            log.Fatal(err)
        }

        switch state {
        case "start":
            if delim, ok := token.(json.Delim); ok && delim == '{' {
                state = "object"
            } else {
                log.Fatal("Expected object")
            }
        case "object":
            switch t := token.(type) {
            case json.Delim:
                if t == '}' {
                    // End of object
                    state = "end"
                } else if t == ',' {
                    // Next property
                    continue
                } else if t == '[' {
                    // Array found
                    state = "array"
                }

                if t == ':' {
                    // Property value expected
                    state = "prop_value"
                }
            case string:
                // Property name
                fmt.Printf("Property '%s'\n", t)
            default:
                // Property value
                fmt.Printf("Value: %v\n", t)
            }
        case "array":
            if delim, ok := token.(json.Delim); ok && delim == ']' {
                // End of array
                state = "object"
            } else if token == json.Delim('{') {
                // Array item object
                fmt.Printf("Item:\n")
                state = "item"
            }
        case "item":
            switch t := token.(type) {
            case json.Delim:
                if t == '}' {
                    // End of item object
                    fmt.Printf("\n")
                    state = "array"
                } else if t == ',' {
                    // Next item property
                    fmt.Printf(",\n")
                    continue
                }
            case string:
                // Item property name
                fmt.Printf("\t'%s'", t)
            default:
                // Item property value
                fmt.Printf(": %v", t)
            }
        case "prop_value":
            // Decode the property value
            var value interface{}
            if err := decoder.Decode(&value); err != nil {
                log.Fatal(err)
            }
            fmt.Printf("Value: %v\n", value)
            state = "object"
        }
    }
}

Apabila dipanggil dengan JSON respons, fungsi ini akan mencetak nama dan nilai sifat, serta item individu dalam tatasusunan.

Kesimpulan

Menggunakan json.Decoder dan Decoder.Token() dalam event-driven pemprosesan membolehkan kami menghuraikan respons JSON yang besar secara berperingkat, mengelakkan isu penggunaan memori dan membolehkan pemprosesan data yang cekap semasa ia mengalir masuk.

Atas ialah kandungan terperinci Bagaimana untuk Menyahkod JSON Penstriman Besar dengan Cekap dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn