golang把io.ReadCloser类型转化为[]byte

前端之家收集整理的这篇文章主要介绍了golang把io.ReadCloser类型转化为[]byte前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
  1. //比如要解析resp.Body(io.ReadCloser),我们可以这样处理
  2. body,err:=IoUtil.ReadAll(resp.Body)

接着,我们继续分析分析函数

  1. funcReadAll(rio.Reader)([]byte,error){
  2. returnreadAll(r,bytes.MinRead)//constMinRead=512
  3. }
  4. //
  5. funcreadAll(rio.Reader,capacityint64)(b[]byte,errerror){
  6. buf:=bytes.NewBuffer(make([]byte,capacity))
  7. //funcNewBuffer(buf[]byte)*Buffer{return&Buffer{buf:buf}}一个新的buffer实例
  8.  
  9. deferfunc(){
  10. e:=recover()
  11. ife==nil{
  12. return
  13. }
  14. //buf太大会返回相应错误
  15. ifpanicErr,ok:=e.(error);ok&&panicErr==bytes.ErrTooLarge{
  16. err=panicErr
  17. }else{
  18. panic(e)
  19. }
  20. }()
  21. _,err=buf.ReadFrom(r)//关键就是这个家伙
  22. returnbuf.Bytes(),err
  23. }

来继续看看 buf.ReadFrom的实现吧:

  1. //先看一下Buffer的定义,有帮助下面理解
  2. typeBufferstruct{
  3. buf[]byte//最新数据存放在buf[off:len(buf)]
  4. offint//从&buf[off]开始读,从&buf[len(buf)]开始写
  5. runeBytes[utf8.UTFMax]byte//avoidallocationofsliceoneachWriteByteorRune
  6. bootstrap[64]byte
  7. //memorytoholdfirstslice;helpssmallbuffers(Printf)avoidallocation.
  8. lastReadreadOp//lastreadoperation,sothatUnread*canworkcorrectly.
  9. }
  10.  
  11.  
  12. func(b*Buffer)ReadFrom(rio.Reader)(nint64,errerror){
  13. b.lastRead=opInvalid//0
  14. ifb.off>=len(b.buf){
  15. b.Truncate(0)//还没有写就想读,清空buf
  16. }
  17. for{
  18. iffree:=cap(b.buf)-len(b.buf);free<MinRead{
  19. //free的大小是总容量-现在占有长度
  20. newBuf:=b.buf
  21. ifb.off+free<MinRead{
  22. //分配更大空间,分配失败会报错
  23. newBuf=makeSlice(2*cap(b.buf)+MinRead)
  24. }
  25. //把读的内容b.buf[b.off:]拷贝到newbuf前面去
  26. copy(newBuf,b.buf[b.off:])
  27. //读写之间的差距就是应该读的buf
  28. b.buf=newBuf[:len(b.buf)-b.off]
  29. b.off=0
  30. }
  31. //把io.Reader内容写到buf的free中去
  32. m,e:=r.Read(b.buf[len(b.buf):cap(b.buf)])
  33. //重新调整buf的大小
  34. b.buf=b.buf[0:len(b.buf)+m]
  35. n+=int64(m)
  36. //读到尾部就返回
  37. ife==io.EOF{
  38. break
  39. }
  40. ife!=nil{
  41. returnn,e
  42. }
  43. }
  44. returnn,nil//erriSEOF,soreturnnilexplicitly
  45. }

接下来再来看看是怎么Read进buf里面去的吧:

  1. func(b*Buffer)Read(p[]byte)(nint,errerror){
  2. b.lastRead=opInvalid
  3. ifb.off>=len(b.buf){
  4. //Bufferisempty,resettorecoverspace.
  5. b.Truncate(0)
  6. iflen(p)==0{
  7. return
  8. }
  9. return0,io.EOF
  10. }
  11. //就是这里咯,把b.buf[b.off:]的值写到p中去,记住copy(s1,s2)是s2写到s1中去,不要弄反咯
  12. //而且此Buffer其实是io.ReadCloser接口转化的类型
  13. n=copy(p,b.buf[b.off:])
  14. b.off+=n
  15. ifn>0{
  16. b.lastRead=opRead
  17. }
  18. return
  19. }

总之,这里分析比较少脑筋的代码就是那个ReadFrom里面修改buf大小那里的逻辑,确实有点绕。。。。。。

猜你在找的Go相关文章