- //比如要解析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
- }