我有一个对象。我使用将对象编码为json json.Encoder。
json.Encoder
我怎样才能测量json字符串的大小?
io.Writer并且json.Encoder不公开也不维护写入字节数。
io.Writer
一种方法是先使用内置函数json.Marshal()将[]byte其编入其长度来封送该值len()。您要查找的位数是长度乘以8(1字节为8位)。之后,您必须手动将字节片写入输出中。对于小型类型,这不是问题,但是对于大型结构/值,可能是不希望的。另外,也没有必要的工作将其编组,获取其长度并手动编写切片。
json.Marshal()
[]byte
len()
一种更好,更优雅的方法是使用 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
Count
现在,您创建一个CounterWr传递io.Writer当前使用的的CounterWr值,然后将该值传递给json.NewEncoder(),您可以CounterWr.Count直接从中访问写入的字节数。
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.Count并且Buffer.Len()应该匹配)。
bytes.Buffer
Buffer.Len()
输出:
Count: 20 bytes, 160 bits Verif: 20 bytes, 160 bits
在Go Playground上尝试一下。
笔记:
如果您也对其他值进行编码,cw.Count则将是当然的总字节数(而不仅仅是最后一个值)。如果只想获取最后一个编码值的大小,请cw.Count在调用之前存储Encoder.Encode(),然后计算与编码后得到的计数之差。或简单地设置cw.Count为0编码前(是的,您也可以更改该字段):
cw.Count
Encoder.Encode()
0
cw.Count = 0