bytes.Buffer
bytes.Buffer是一个实现了读写方法的可变大小的字节缓冲。本类型的零值是一个空的可用于读写的缓冲。
bytes.Buffer强大之处是封装了一些操作函数,比如ReadRune 、ReadString(delim byte)、 writeTo等等,底层是先对buf扩容,再将string进行copy到buff中来,性能相比直接操作byte数组会差一些。
//直接操作byte数组
//BenchmarkBuffers/ByteSlice 47869220 23.3 ns/op
//BenchmarkBuffers/ByteSlice-2 58386488 22.1 ns/op
//BenchmarkBuffers/ByteSlice-4 58312720 21.5 ns/op
//BenchmarkBuffers/ByteSlice-8 53119909 21.6 ns/op
//标准库bytes.Buffer
//BenchmarkBuffers/BytesBuffer 44326240 27.4 ns/op
//BenchmarkBuffers/BytesBuffer-2 43723957 27.9 ns/op
//BenchmarkBuffers/BytesBuffer-4 43525412 27.2 ns/op
//BenchmarkBuffers/BytesBuffer-8 43477472 27.4 ns/op
func BenchmarkBuffers(b *testing.B) {
str := strings.Repeat("A", 1024)
slice := make([]byte, 1024)
buf := bytes.NewBuffer(slice)
b.Run("ByteSlice", func(b *testing.B) {
for i := 0; i < b.N; i++ {
slice = append(slice, str...)
slice = slice[:0]
}
})
b.Run("BytesBuffer", func(b *testing.B) {
for i := 0; i < b.N; i++ {
buf.WriteString(str)
buf.Reset()
}
})
}
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
lastRead readOp // last read operation, so that Unread* can work correctly.
}
这东西看来看去就是一个缓冲区,好像没什么卵用,就是一个用来暂时存放数据的地方。
里面就两种方法,一种是Read一种是Write。
Read方法,主要是从buff中读取数据
读的时候buff里面的指针跟着增加偏移,也就是说,读过的数据一般情况下是没法再读一次的,
但这包里有 UnreadRune、UnreadByte这种方法,可以把off往回退一些值,但是作用有限,UnreadRune只能回退一个rune占用的字节并且必须要之前调用过 ReadRune方法才行,UnreadByte只能回退一个字节,还不能重复回退,这有个毛用啊,Read方法读出来的数据根本没法把off回退回去。
// Read reads the next len(p) bytes from the buffer or until the buffer
// is drained. The return value n is the number of bytes read. If the
// buffer has no data to return, err is io.EOF (unless len(p) is zero);
// otherwise it is nil.
//尽量把p填满,返回填充的字节数。如果本身这个buff是nil或者读取len(p)个字节成功,那err就会返回nil。没填满err//就返回EOF。
func (b *Buffer) Read(p []byte) (n int, err error) {
b.lastRead = opInvalid
if b.empty() {
// Buffer is empty, reset to recover space.
b.Reset()
if len(p) == 0 {
return 0, nil
}
return 0, io.EOF
}
n = copy(p, b.buf[b.off:])
b.off += n
if n > 0 {
b.lastRead = opRead
}
return n, nil
}
Write方法主要往buff里写入数据
write往里面写数据的时候会自动扩大buff的容量,
在gorw方法里面:capacity如果扩大到超过
2*c + n > maxInt 会触发panic (c为buff的capacity)
const maxInt = int(^uint(0) >> 1) //本机的int是64位,所以这里是2的63次方,前面一位是符号位,单位是字节,分配得快要到64位系统最大内存容量了,这游戏能玩?,一般不会这样的,绝对不会,我说的。
// Write appends the contents of p to the buffer, growing the buffer as
// needed. The return value n is the length of p; err is always nil. If the
// buffer becomes too large, Write will panic with ErrTooLarge.
func (b *Buffer) Write(p []byte) (n int, err error) {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(len(p))
if !ok {
m = b.grow(len(p))
}
return copy(b.buf[m:], p), nil
}
包里面其他方法都是以Read和Write方法的延伸,可以方便的根据分隔符读取字符串、写入到指定writer等。
本作品采用《CC 协议》,转载必须注明作者和本文链接