golang bytes buffer代码剖析
发布时间:2020-12-16 18:38:04 所属栏目:大数据 来源:网络整理
导读://上数据结构,bytesBuffertypeBufferstruct{buf[]byte//byte切片offint//从buf[off]地址读数据,从buf[len(buf)]地址写数据runeBytes[utf8.UTFMax]byte//avoidallocationofsliceoneachWriteByteorRunebootstrap[64]byte//memorytoholdfirstslice;helpssmallb
//上数据结构,bytesBuffer typeBufferstruct{ buf[]byte//byte切片 offint//从&buf[off]地址读数据,从&buf[len(buf)]地址写数据 runeBytes[utf8.UTFMax]byte//avoidallocationofsliceoneachWriteByteorRune bootstrap[64]byte//memorytoholdfirstslice;helpssmallbuffers(Printf)avoidallocation. lastReadreadOp//lastreadoperation,sothatUnread*canworkcorrectly. } 再来看看我们bytes Buffer里面write是怎么实现的 func(b*Buffer)WriteString(sstring)(nint,errerror){ b.lastRead=opInvalid///Non-readoperation不需要读的标志等于0 m:=b.grow(len(s))//增长大小(准确来说是调整数据在buf中位置,也不一定增长),m当然是老数据末尾 returncopy(b.buf[m:],s),nil//copy一下数据,从m开始 } 最最重要的看过来 func(b*Buffer)grow(nint)int{ m:=b.Len()//func(b*Buffer)Len()int{returnlen(b.buf)-b.off} //m就是buf的len减去(-)b.off(读开始位置) ifm==0&&b.off!=0{ b.Truncate(0)//下面给予显示 } //调整大小和位置 iflen(b.buf)+n>cap(b.buf){ varbuf[]byte ifb.buf==nil&&n<=len(b.bootstrap){ buf=b.bootstrap[0:]//这个bootstrap缓存了buf的切片,说是防止重allocation }elseifm+n<=cap(b.buf)/2{//二倍申请新的slice的原则 copy(b.buf[:],b.buf[b.off:]) buf=b.buf[:m] }else{ //notenoughspaceanywhere buf=makeSlice(2*cap(b.buf)+n) copy(buf,b.buf[b.off:]) } b.buf=buf b.off=0 } b.buf=b.buf[0:b.off+m+n]//赋值咯 returnb.off+m } 再看看它用到过的函数Truncate函数,缩减切片 func(b*Buffer)Truncate(nint){ b.lastRead=opInvalid switch{ casen<0||n>b.Len(): panic("bytes.Buffer:truncationoutofrange") casen==0: //Reusebufferspace. b.off=0 } b.buf=b.buf[0:b.off+n] } makeSlice函数 funcmakeSlice(nint)[]byte{ //Ifthemakefails,giveaknownerror. deferfunc(){ ifrecover()!=nil{ panic(ErrTooLarge) } }() returnmake([]byte,n)//其实还是调用这个make } 最后看看一个使用示例咯 packagemain import( "bytes" "fmt" "strconv" "time" ) funcmain(){ varbufferbytes.Buffer ttime:=time.Now().UnixNano() fori:=0;i<10000000;i++{ buffer.WriteString(strconv.Itoa(i)) } ttime1:=time.Now().UnixNano() //取内容buffer.Bytes()或者buffer.String() fmt.Printf("timecal%f%dn",float64(ttime1-ttime)/float64(1*time.Second),len(buffer.String())) } 总结:bytes buffer:就是写byte或者字符串string的一个容器 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |