这个binary.read如何知道何时停止?

时间:2016-04-13 12:51:09

标签: go

请注意这是伪代码,我在总结。我正在从函数内部读取一些源代码:

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的下一个二进制读取然后找到了东西?

1 个答案:

答案 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读取的字节数使用指定的字节顺序进行解码,并写入数据的连续字段。