>  기사  >  백엔드 개발  >  메모리에 객체를 로드하지 않고 JSON에서 대규모 데이터 스트림을 어떻게 인코딩할 수 있습니까?

메모리에 객체를 로드하지 않고 JSON에서 대규모 데이터 스트림을 어떻게 인코딩할 수 있습니까?

Susan Sarandon
Susan Sarandon원래의
2024-10-28 04:08:30215검색

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

인메모리 객체 로딩 없이 JSON에서 대규모 데이터 스트림 인코딩

광범위한 데이터 스트림과 관련된 시나리오에서 json 모든 개체를 동시에 메모리에 인코딩하려고 하면 패키지에 제한이 발생할 수 있습니다. 다음 시나리오를 고려하십시오.

<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>

json.Encoder를 사용하여 마샬링을 시도하는 동안 지원되지 않는 유형 chan 문자열로 인해 오류가 발생합니다.

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

이와 같은 상황에서는 수동으로 구성합니다. JSON 문자열이 필요해집니다. 그러나 더 효율적인 메커니즘이 바람직합니다.

json.Marshaler 인터페이스가 이 구조와 유사하다면 인코딩 프로세스가 더 간단할 것입니다.

<code class="go">type Marshaler interface {
    MarshalJSON(io.Writer) error
}</code>

안타깝게도 현재 인코딩/json 패키지는 그런 메커니즘이 부족해요. 따라서 내장 패키지를 사용자 정의해야 할 수도 있습니다. 이를 달성하려면 인코딩/json/encode.go의 ReflectValueQuoted 함수를 수정해야 합니다. 특히, 배열 케이스(Slice로 대체)와 채널 케이스 추가에 중점을 두어야 합니다.

<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>

참고: 채널 케이스에는 다음과 같은 추가 확인이 필요할 수 있습니다. 위 코드에서는 명확하지 않습니다.

이러한 수정 사항을 구현하면 인코딩 프로세스 내에서 채널이 배열과 유사하게 처리됩니다. 이 수정 사항은 잠재적으로 포함될 수 있도록 인코딩/json 패키지에 패치로 제출될 수 있습니다.

위 내용은 메모리에 객체를 로드하지 않고 JSON에서 대규모 데이터 스트림을 어떻게 인코딩할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.