Golang bytes.buffer详解

Python011

Golang bytes.buffer详解,第1张

Buffer 介绍

Buffer 是 bytes 包中的一个 type Buffer struct{…}

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.

(是一个变长的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一个 空的 buffer,但是可以使用)

Buffer 就像一个集装箱容器,可以存东西,取东西(存取数据)

创建缓冲器

输出

写入到缓冲器

buffer在new的时候是空的,也是可以直接Write的

Write

结果

WriteString

结果

WriteByte

WriteRune

结果

从缓冲器中写出

读出缓冲器

Read

ReadByte

返回缓冲器头部的第一个byte

ReadRun

ReadRune方法,返回缓冲器头部的第一个rune

为什么n==3,而n1==1呢?我们看下ReadRune 的源码

ReadBytes

ReadBytes方法,需要一个byte作为分隔符,读的时候从缓冲器里找出第一个出现的分隔符,缓冲器头部开始到分隔符之间的byte返回。

相当于有一个分隔符

ReadString

和readBytes方法类似

读入缓冲器

ReadFrom方法,从一个实现io.Reader接口的r,把r的内容读到缓冲器里,n返回读的数量

从缓冲器取出

Next方法,返回前n个byte(slice),原缓冲器变

缓冲区原理介绍

go字节缓冲区底层以字节切片做存储,切片存在长度len与容量cap, 缓冲区写从长度len的位置开始写,当len>cap时,会自动扩容。缓冲区读会从内置标记off位置开始读(off始终记录读的起始位置),当off==len时,表明缓冲区已全部读完

并重置缓冲区(len=off=0),此外当将要内容长度+已写的长度(即len) <= cap/2时,缓冲区前移覆盖掉已读的内容(off=0,len-=off),从避免缓冲区不断扩容

Go中的binary包实现了简单的数字与字节序列的转换以及变长值的编解码

package main

import ( "fmt" "bytes" "encoding/binary" ) func main(){ n := 0x12345678 bytesBuffer := bytes.NewBuffer([]byte{}) //BigEndian 大端顺序存储 LittleEndian小端顺序存储 binary.Write(bytesBuffer, binary.BigEndian, int32(n)) data:=bytesBuffer.Bytes() fmt.Printf("[0]: %#x addr:%#x\n",data[0],&data[0]) fmt.Printf("[0]: %#x addr:%#x\n",data[1],&data[1]) fmt.Printf("[0]: %#x addr:%#x\n",data[2],&data[2]) fmt.Printf("[0]: %#x addr:%#x\n",data[3],&data[3]) }

输出

[0]: 0x12 addr:0xc042010248 [1]: 0x34 addr:0xc042010249 [2]: 0x56 addr:0xc04201024a [3]: 0x78 addr:0xc04201024b

也可以使用下面的方式

n := 0x12345678 var data []byte = make([]byte,4) //操作的都是无符号整型 binary.BigEndian.PutUint32(data,uint32(n))

可以使用下面的方式判断当前系统的字节序类型

const INT_SIZE int = int(unsafe.Sizeof(0))

//判断我们系统中的字节序类型 func systemEdian() { var i int = 0x1 bs := (*[INT_SIZE]byte)(unsafe.Pointer(&i)) if bs[0] == 0 { fmt.Println("system edian is little endian") } else { fmt.Println("system edian is big endian") } }