加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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大小那里的逻辑,确实有点绕。。。。。。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读