首页 文章资讯内容详情

Golang bytes.buffer详解

2026-06-01 5 花语

本文内容纲要:

原文: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