Golang bytes.buffer详解
本文内容纲要:
原文:https://www.jianshu.com/p/e53083132a25
Buffer介绍
Buffer是bytes包中的一个typeBufferstruct{…}
Abufferisavariable-sizedbufferofbyteswithReadandWritemethods.ThezerovalueforBufferisanemptybufferreadytouse.
(是一个变长的buffer,具有Read和Write方法。Buffer的零值是一个空的buffer,但是可以使用)
Buffer就像一个集装箱容器,可以存东西,取东西(存取数据)
创建缓冲器
funcmain(){
buf1:=bytes.NewBufferString("hello")
buf2:=bytes.NewBuffer([]byte("hello"))
buf3:=bytes.NewBuffer([]byte{'h','e','l','l','o'})
fmt.Printf("%v,%v,%v\n",buf1,buf2,buf3)
fmt.Printf("%v,%v,%v\n",buf1.Bytes(),buf2.Bytes(),buf3.Bytes())
buf4:=bytes.NewBufferString("")
buf5:=bytes.NewBuffer([]byte{})
fmt.Println(buf4.Bytes(),buf5.Bytes())
}
输出
hello,hello,hello
[104101108108111],[104101108108111],[104101108108111]
[][]
写入到缓冲器
buffer在new的时候是空的,也是可以直接Write的
Write
func(b*Buffer)Write(p[]byte)(nint,errerror)
funcmain(){
s:=[]byte("world")
buf:=bytes.NewBufferString("hello")
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
buf.Write(s)
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
}
结果
hello,[104101108108111]
helloworld,[10410110810811132119111114108100]
WriteString
func(b*Buffer)WriteString(sstring)(nint,errerror)
funcmain(){
s:="world"
buf:=bytes.NewBufferString("hello")
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
buf.WriteString(s)
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
}
结果
hello,[104101108108111]
helloworld,[10410110810811132119111114108100]
缓冲区原理介绍
go字节缓冲区底层以字节切片做存储,切片存在长度len与容量cap,缓冲区写从长度len的位置开始写,当len>cap时,会自动扩容。缓冲区读会从内置标记off位置开始读(off始终记录读的起始位置),当off==len时,表明缓冲区已全部读完
并重置缓冲区(len=off=0),此外当将要内容长度+已写的长度(即len)<=cap/2时,缓冲区前移覆盖掉已读的内容(off=0,len-=off),从避免缓冲区不断扩容
funcmain(){
byteSlice:=make([]byte,20)
byteSlice[0]=1//将缓冲区第一个字节置1
byteBuffer:=bytes.NewBuffer(byteSlice)//创建20字节缓冲区len=20off=0
c,_:=byteBuffer.ReadByte()//off+=1
fmt.Printf("len:%d,c=%d\n",byteBuffer.Len(),c)//len=20off=1打印c=1
byteBuffer.Reset()//len=0off=0
fmt.Printf("len:%d\n",byteBuffer.Len())//打印len=0
byteBuffer.Write([]byte("hellobytebuffer"))//写缓冲区len+=17
fmt.Printf("len:%d\n",byteBuffer.Len())//打印len=17
byteBuffer.Next(4)//跳过4个字节off+=4
c,_=byteBuffer.ReadByte()//读第5个字节off+=1
fmt.Printf("第5个字节:%d\n",c)//打印:111(对应字母o)len=17off=5
byteBuffer.Truncate(3)//将未字节数置为3len=off+3=8off=5
fmt.Printf("len:%d\n",byteBuffer.Len())//打印len=3为未读字节数上面len=8是底层切片长度
byteBuffer.WriteByte(96)//len+=1=9将y改成A
byteBuffer.Next(3)//len=9off+=3=8
c,_=byteBuffer.ReadByte()//off+=1=9c=96
fmt.Printf("第9个字节:%d\n",c)//打印:96
}
demo1
packagemain
import"bytes"
import"log"
funcmain(){
buf:=&bytes.Buffer{}
buf.WriteString("abcdefg")
str,_:=buf.ReadString('?')
log.Println("str=",str)
log.Println("buff=",buf.String())
}
输出:
[root@localhost]#gorunbuffer.go
2020/06/0519:12:42str=abcdefg
2020/06/0519:12:42buff=
demo2
//MyBuffer2projectmain.go
packagemain
import(
"bytes"
"log"
"os"
)
funcmain(){
log.SetFlags(log.Lshortfile)
buff:=bytes.NewBufferString("123456789")
log.Println("buff=",buff.String())
s:=make([]byte,4)
n,_:=buff.Read(s)
log.Println("buff=",buff.String())
log.Println("s=",string(s))
log.Println("n=",n)
n,_=buff.Read(s)
log.Println("buff=",buff.String())
log.Println("s=",string(s))
log.Println("n=",n)
n,_=buff.Read(s)
log.Println("buff=",buff.String())
log.Println("s=",string(s))
log.Println("n=",n)
buff.Reset()
buff.WriteString("abcdefg")
log.Println("buff=",buff.String())
b,_:=buff.ReadByte()
log.Println("b=",string(b))
log.Println("buff=",buff.String())
b,_=buff.ReadByte()
log.Println("b=",string(b))
log.Println("buff=",buff.String())
bs,_:=buff.ReadBytes('e')
log.Println("bs=",string(bs))
log.Println("buff=",buff.String())
buff.Reset()
buff.WriteString("编译输出GO")
r,l,_:=buff.ReadRune()
log.Println("r=",r,",l=",l,",string(r)=",string(r))
buff.Reset()
buff.WriteString("qwer")
str,_:=buff.ReadString('?')
log.Println("str=",str)
log.Println("buff=",buff.String())
buff.WriteString("qwer")
str,_=buff.ReadString('w')
log.Println("str=",str)
log.Println("buff=",buff.String())
file,_:=os.Open("doc.go")
buff.Reset()
buff.ReadFrom(file)
log.Println("doc.go=",buff.String())
buff.Reset()
buff.WriteString("中国人")
cbyte:=buff.Bytes()
log.Println("cbyte=",cbyte)
}
输出:
C:/Go/bin/go.exebuild-i[D:/golang/src/MyBuffer2]
成功:进程退出代码0.
D:/golang/src/MyBuffer2/MyBuffer2.exe[D:/golang/src/MyBuffer2]
main.go:13:buff=123456789
main.go:17:buff=56789
main.go:18:s=1234
main.go:19:n=4
main.go:22:buff=9
main.go:23:s=5678
main.go:24:n=4
main.go:27:buff=
main.go:28:s=9678
main.go:29:n=1
main.go:33:buff=abcdefg
main.go:36:b=a
main.go:37:buff=bcdefg
main.go:40:b=b
main.go:41:buff=cdefg
main.go:44:bs=cde
main.go:45:buff=fg
main.go:50:r=32534,l=3,string(r)=编
main.go:55:str=qwer
main.go:56:buff=
main.go:60:str=qw
main.go:61:buff=er
main.go:66:doc.go=//MyBuffer2projectdoc.go
/*
MyBuffer2document
*/
packagemain
main.go:71:cbyte=[228184173229155189228186186]
成功:进程退出代码0.
本文内容总结:
原文链接:https://www.cnblogs.com/wangjq19920210/p/13051447.html