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 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!