go 语言 buffer.truncate 分析
对于Golang的初学者,Truncate
方法的行为使人迷惑,它不是从 buffer
的头部截取 n 个
字节,而是丢弃除了前n个
未读取的字节之外的所有未读取的字节,也是就只保留已读取的字节和还没有读取的前n个
字节。这种逻辑确实让人不太适应
// Truncate discards all but the first n unread bytes from the buffer
// but continues to use the same allocated storage.
// It panics if n is negative or greater than the length of the buffer.
func (b *Buffer) Truncate(n int) {
if n == 0 {
b.Reset()
return
}
b.lastRead = opInvalid
if n < 0 || n > b.Len() {
panic("bytes.Buffer: truncation out of range")
}
b.buf = b.buf[:b.off+n]
}
从源码的注释中还可以看到,截取后使用原 buffer
保存保留下来的节字,不再额外占用内存空间。同时 n 的大小不能超过未读取字节的长度(第10行)
func truncate() {
var buffer bytes.Buffer
str := "Simple byte buffer for marshaling data."
buffer.WriteString(str)
p := make([]byte, 8)
buffer.Read(p) // Simple b
fmt.Println(string(p))
buffer.Truncate(10) // 截断到前10个未读节字 Simple byte buffer
buffer.Read(p) // 读取8个字节
fmt.Println(string(p)) // yte buff
}
p := make([]byte, 8)
先读取了8个字节buffer.Truncate(10)
再从没有读取的字节中取出10个,丢掉其余未读取的字节,把已读取的8个字节和取出的10个字节保存到buffer
中,此时buffer中的内容为Simple byte buffer
buffer.Read(p)
再读取8个字节,注意:这里不是从 buffer 的头部读取,而是从未读取处开始读取,即从y
开始读取