编码为JSON的对象的位大小?

时间:2016-06-08 11:43:56

标签: json go encoding

我有一个对象。我使用json.Encoder将对象编码为json。

如何在任一位中测量json字符串的大小?

1 个答案:

答案 0 :(得分:1)

io.Writerjson.Encoder不会公开或保持写入的字节数。

一种方法是首先使用json.Marshal()将值编组到[]byte中,我们可以使用内置len()函数获取其长度。您寻找的位数是长度乘以8(1个字节是8位)。之后,您必须手动将字节切片写入输出。对于小型,这不是问题,但对于大型结构/值可能是不合需要的。还有不必要的工作编组,获取其长度并手动编写切片。

更好,更优雅的方法是使用embedding扩展任何编写器的功能来管理写入的字节:

type CounterWr struct {
    io.Writer
    Count int
}

func (cw *CounterWr) Write(p []byte) (n int, err error) {
    n, err = cw.Writer.Write(p)
    cw.Count += n
    return
}

CounterWr类型会自动管理其Count字段中可以随时检查/检查的写入字节数。

现在,您创建我们CounterWr的值,通过您当前使用的io.Writer,然后将此CounterWr值传递给json.NewEncoder(),您就可以访问直接从CounterWr.Count写入的字节。

使用示例:

type Something struct {
    S string
    I int
}


buf := &bytes.Buffer{}

// Any writer, not just a buffer!
var out io.Writer = buf
cw := &CounterWr{Writer: out}

s := Something{"hello", 4}
if err := json.NewEncoder(cw).Encode(s); err != nil {
    panic(err)
}

fmt.Printf("Count: %d bytes, %d bits\n", cw.Count, cw.Count*8)
fmt.Printf("Verif: %d bytes, %d bits\n", buf.Len(), buf.Len()*8)

出于验证目的,我们还会打印我们用作输出的bytes.Buffer的长度(CounterWr.CountBuffer.Len()应匹配)。

输出:

Count: 20 bytes, 160 bits
Verif: 20 bytes, 160 bits

Go Playground上尝试。

备注:

如果您也编码其他值,cw.Count将是当然总字节数(而不仅仅是最后一个值的字节数)。如果您只想获取最后一个编码值的大小,请在调用cw.Count之前存储Encoder.Encode(),并计算编码后获得的计数差异。或者只需在编码前将cw.Count设置为0(是的,您也可以更改该字段):

cw.Count = 0