json.Decoder
の方法を使用し、データ構造全体をメモリにデシリアライズしないようにする方法(テスト済み)です。 JSONドキュメントが非常に大きく、メモリオーバーヘッドを避けたいのであれば、ほとんどの場合、楽しく、そのメソッドをどのように使用できるかを説明するために行われます。
// For example
r, w := os.Stdin, os.Stdout
dec := json.NewDecoder(r)
// Avoids any round-trip loss by leaving numbers un-parsed
dec.UseNumber()
// Current state (in an object or in an array; following the open
// delim, or a key, or a value). The decoder has its own stack pretty
// like this one, but it's private, so keep our own.
const (
jsonArrayStart = iota
jsonArrayVal
jsonObjectStart
jsonObjectKey
jsonObjectVal
)
stack := []byte{}
for {
t, err := dec.Token()
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
switch val := t.(type) {
case json.Delim:
// Copy delimiters out, and push/pop the state stack as appropriate
w.WriteString(string([]rune{rune(val)}))
switch val {
case '[':
stack = append(stack, jsonArrayStart)
case '{':
stack = append(stack, jsonObjectStart)
case ']', '}':
stack = stack[:len(stack)-1]
}
// The rest of the cases just copy values out
case nil:
w.WriteString("null")
case json.Number:
w.WriteString(string(val))
case bool:
if val {
w.WriteString("true")
} else {
w.WriteString("false")
}
case string:
// Modify strings if called for (shortenString needs to be provided)
if len(val) >= 85 {
val = shortenString(val)
}
encoded, err := json.Marshal(val)
if err != nil {
log.Fatal(err)
}
w.Write(encoded)
}
if dec.More() {
// If there's more in the current array/object, write a colon or comma
// (if we just wrote a key/value), and set the next state.
// Arrays start with a value, and follow with more values.
// Objects start with a key and alternate between key and value.
switch stack[len(stack)-1] {
case jsonArrayStart:
stack[len(stack)-1] = jsonArrayVal
case jsonArrayVal:
w.WriteString(",")
// State remains jsonArrayVal
case jsonObjectStart:
stack[len(stack)-1] = jsonObjectKey
case jsonObjectKey:
w.WriteString(":")
stack[len(stack)-1] = jsonObjectVal
case jsonObjectVal:
w.WriteString(",")
stack[len(stack)-1] = jsonObjectKey
}
} else {
if len(stack) == 0 {
// End after the first complete value (array/object) in the stream
break
}
if stack[len(stack)-1] == jsonObjectKey {
// Should never happen
log.Fatal("Object key without a value?")
}
}
}
「go」にする必要がありますか? – yeya
はい。言語はGoです – user7425610