> 백엔드 개발 > Golang > Go에서 대규모 스트리밍 JSON을 효율적으로 디코딩하는 방법은 무엇입니까?

Go에서 대규모 스트리밍 JSON을 효율적으로 디코딩하는 방법은 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2025-01-02 20:03:40
원래의
341명이 탐색했습니다.

How to Efficiently Decode Large Streaming JSON in Go?

Go에서 스트리밍 JSON을 디코딩하는 방법

대규모 JSON 응답으로 작업할 때 디코딩하기 전에 전체 응답을 메모리에 로드하는 것은 이상적이지 않습니다. ioutil.ReadAll 함수를 사용하면 대규모 JSON 페이로드를 처리할 때 메모리 문제가 발생할 수 있습니다. 이 기사에서는 메모리 소비 문제를 피하면서 스트리밍되는 JSON 데이터를 즉시 디코딩하는 방법을 살펴봅니다.

json.Decoder를 사용한 JSON 스트리밍

Go 표준 라이브러리의 json.Decoder는 다음을 제공합니다. JSON 스트림을 점진적으로 구문 분석하는 기능. 이는 Decoder.Token() 메서드를 통해 달성됩니다.

Decoder.Token() 메서드는 사용하지 않고 JSON 스트림의 다음 토큰을 반환합니다. 이를 통해 JSON 데이터의 선택적 구문 분석 및 이벤트 중심 처리가 가능합니다.

JSON 구조 처리

이벤트 중심 구문 분석에는 JSON 구조 내에서 현재 위치를 추적하는 상태 시스템이 필요합니다. 이 상태 시스템을 사용하면 스트림에 나타나는 JSON 데이터의 다양한 부분을 처리할 수 있습니다.

예를 들어 다음 형식의 JSON 응답을 받았다고 가정해 보겠습니다.

{
    "property1": "value1",
    "property2": "value2",
    "array": [
        { "item1": "value3" },
        { "item2": "value4" }
    ]
}
로그인 후 복사

이 JSON 스트림을 점진적으로 구문 분석하고 배열 요소를 별도로 처리하는 함수를 작성할 수 있습니다.

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"
        }
    }
}
로그인 후 복사

JSON 응답과 함께 호출되면 이 함수는 인쇄합니다. 속성 이름과 값은 물론 배열 내의 개별 항목도 포함됩니다.

결론

이벤트 중심 처리에서 json.Decoder 및 Decoder.Token()을 사용하면 대규모 구문 분석을 수행할 수 있습니다. JSON은 점진적으로 응답하여 메모리 소비 문제를 방지하고 스트리밍되는 데이터를 효율적으로 처리할 수 있도록 합니다.

위 내용은 Go에서 대규모 스트리밍 JSON을 효율적으로 디코딩하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿