请注意这是伪代码,我在总结。我正在从函数内部读取一些源代码:
maxKeyLen := 100 * 1024 * 1024
maxValueLen := 100 * 1024 * 1024
var klen, vlen uint32
binary.Read(p.buffer, binary.BigEndian, &klen)
if klen > maxKeyLen {
return nil, nil, fmt.Errorf("key exceeds max len %d, got %d bytes", maxKeyLen, klen)
}
binary.Read在什么时候停止?因为在此之后还有另一个阅读:
key := make([]byte, klen)
_, err := p.buffer.Read(key)
if err != nil {
return nil, nil, err
}
binary.Read(p.buffer, binary.BigEndian, &vlen)
if vlen > maxValueLen {
return nil, nil, fmt.Errorf("value exceeds max len %d, got %d bytes", maxValueLen, vlen)
}
p.buffer通过以下方式定义:
buff := new(bytes.Buffer)
io.Copy(buff, r)
p.buffer = buff
r是传入的一些数据。
起初我认为答案是4字节停止。但这并不正确,因为maxkeylen会检查更多。那么binary.read如何知道何时停止,因为前面有更多的数据,因为vlen的下一个二进制读取然后找到了东西?
答案 0 :(得分:3)
在质疑Go的超级英雄时,请始终参考他们的实际源代码:
https://golang.org/src/encoding/binary/binary.go?s=4201:4264#L132
142 func Read(r io.Reader, order ByteOrder, data interface{}) error {
143 // Fast path for basic types and slices.
144 if n := intDataSize(data); n != 0 {
第144行显示了一个读取已知类型的初始大小,并在该范围内稍后根据需要进行迭代或复制的示例。
在上面的代码示例中,它将是klen的4字节长度,即uint32
。也就是说,它将从p.buffer
读取4个字节到klen。
它在文档中提供了一个提示:
https://golang.org/pkg/encoding/binary/#Read
func Read(r io.Reader, order ByteOrder, data interface{}) error
读取将r中的结构化二进制数据读入数据。数据必须是指向固定大小值或固定大小值切片的指针。从r读取的字节数使用指定的字节顺序进行解码,并写入数据的连续字段。