golang把io.ReadCloser类型转化为[]byte
发布时间:2020-12-16 18:39:23 所属栏目:大数据 来源:网络整理
导读://比如要解析resp.Body(io.ReadCloser),我们可以这样处理body,err:=ioutil.ReadAll(resp.Body) 接着,我们继续分析分析函数 funcReadAll(rio.Reader)([]byte,error){returnreadAll(r,bytes.MinRead)//constMinRead=512}//funcreadAll(rio.Reader,capacityin
//比如要解析resp.Body(io.ReadCloser),我们可以这样处理 body,err:=ioutil.ReadAll(resp.Body) 接着,我们继续分析分析函数 funcReadAll(rio.Reader)([]byte,error){ returnreadAll(r,bytes.MinRead)//constMinRead=512 } // funcreadAll(rio.Reader,capacityint64)(b[]byte,errerror){ buf:=bytes.NewBuffer(make([]byte,capacity)) //funcNewBuffer(buf[]byte)*Buffer{return&Buffer{buf:buf}}一个新的buffer实例 deferfunc(){ e:=recover() ife==nil{ return } //buf太大会返回相应错误 ifpanicErr,ok:=e.(error);ok&&panicErr==bytes.ErrTooLarge{ err=panicErr }else{ panic(e) } }() _,err=buf.ReadFrom(r)//关键就是这个家伙 returnbuf.Bytes(),err } 来继续看看 buf.ReadFrom的实现吧: //先看一下Buffer的定义,有帮助下面理解 typeBufferstruct{ buf[]byte//最新数据存放在buf[off:len(buf)] offint//从&buf[off]开始读,从&buf[len(buf)]开始写 runeBytes[utf8.UTFMax]byte//avoidallocationofsliceoneachWriteByteorRune bootstrap[64]byte //memorytoholdfirstslice;helpssmallbuffers(Printf)avoidallocation. lastReadreadOp//lastreadoperation,sothatUnread*canworkcorrectly. } func(b*Buffer)ReadFrom(rio.Reader)(nint64,errerror){ b.lastRead=opInvalid//0 ifb.off>=len(b.buf){ b.Truncate(0)//还没有写就想读,清空buf } for{ iffree:=cap(b.buf)-len(b.buf);free<MinRead{ //free的大小是总容量-现在占有长度 newBuf:=b.buf ifb.off+free<MinRead{ //分配更大空间,分配失败会报错 newBuf=makeSlice(2*cap(b.buf)+MinRead) } //把读的内容b.buf[b.off:]拷贝到newbuf前面去 copy(newBuf,b.buf[b.off:]) //读写之间的差距就是应该读的buf b.buf=newBuf[:len(b.buf)-b.off] b.off=0 } //把io.Reader内容写到buf的free中去 m,e:=r.Read(b.buf[len(b.buf):cap(b.buf)]) //重新调整buf的大小 b.buf=b.buf[0:len(b.buf)+m] n+=int64(m) //读到尾部就返回 ife==io.EOF{ break } ife!=nil{ returnn,e } } returnn,nil//erriSEOF,soreturnnilexplicitly } 接下来再来看看是怎么Read进buf里面去的吧: func(b*Buffer)Read(p[]byte)(nint,errerror){ b.lastRead=opInvalid ifb.off>=len(b.buf){ //Bufferisempty,resettorecoverspace. b.Truncate(0) iflen(p)==0{ return } return0,io.EOF } //就是这里咯,把b.buf[b.off:]的值写到p中去,记住copy(s1,s2)是s2写到s1中去,不要弄反咯 //而且此Buffer其实是io.ReadCloser接口转化的类型 n=copy(p,b.buf[b.off:]) b.off+=n ifn>0{ b.lastRead=opRead } return } 总之,这里分析比较少脑筋的代码就是那个ReadFrom里面修改buf大小那里的逻辑,确实有点绕。。。。。。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |