MarshalJSON without having all objects in memory at once

后端 未结 2 1658
情歌与酒
情歌与酒 2021-01-13 04:48

I want to use json.Encoder to encode a large stream of data without loading all of it into memory at once.

// I want to marshal this
t := struct         


        
2条回答
  •  不要未来只要你来
    2021-01-13 05:20

    Unfortunately the encoding/json package doesn't have a way to do this yet. What you're doing now (manually) is the best way to do it, without modifying the built-in package.

    If you were to patch encoding/json, you could modify the reflectValueQuoted function in encoding/json/encode.go

    You would want to focus on the Array case (Slice has a fallthrough):

    // Inside switch:
    case reflect.Array:
        e.WriteByte('[')
        n := v.Len()
        for i := 0; i < n; i++ {
            if i > 0 {
                e.WriteByte(',')
            }
            e.reflectValue(v.Index(i))
        }
        e.WriteByte(']')
    

    I'm assuming you'd want to treat channel the same way. It would look something like this:

    // Inside switch:
    case reflect.Chan:
        e.WriteByte('[')
        i := 0
        for {
            x, ok := v.Recv()
            if !ok {
                break
            }
            if i > 0 {
                e.WriteByte(',')
            }
            e.reflectValue(x)
            i++
        }
        e.WriteByte(']')
    

    I haven't done much with channels in reflect, so the above may need other checks.

    If you do end up going this route, you could always submit a patch.

提交回复
热议问题