1 回答
TA贡献1873条经验 获得超9个赞
io.Writer并且json.Encoder不暴露也不维护写入的字节数。
一种方法是首先将使用的值编组为我们可以使用内置函数获得其长度json.Marshal()的值。您寻找的位数是长度乘以 8(1 字节为 8 位)。之后,您必须手动将字节切片写入输出。对于小型类型,这不是问题,但对于大型结构/值可能是不可取的。还有不必要的工作来编组它,获取它的长度并手动编写切片。[]bytelen()
一种更好、更优雅的方法是扩展任何编写器的功能以管理写入的字节,使用嵌入:
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.Count并且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 = 0
- 1 回答
- 0 关注
- 182 浏览
添加回答
举报