博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go把io.ReadCloser类型转化为[]byte
阅读量:5839 次
发布时间:2019-06-18

本文共 2399 字,大约阅读时间需要 7 分钟。

hot3.png

//比如要解析resp.Body(io.ReadCloser),我们可以这样处理body, err := ioutil.ReadAll(resp.Body)

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

func ReadAll(r io.Reader) ([]byte, error) {	return readAll(r, bytes.MinRead) //const MinRead = 512}//func readAll(r io.Reader, capacity int64) (b []byte, err error) {	buf := bytes.NewBuffer(make([]byte, 0, capacity))//func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} } 一个新的buffer实例	defer func() {		e := recover()		if e == nil {			return		}		//buf太大会返回相应错误		if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {			err = panicErr		} else {			panic(e)		}	}()	_, err = buf.ReadFrom(r) //关键就是这个家伙	return buf.Bytes(), err}

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

//先看一下Buffer的定义,有帮助下面理解type Buffer struct {	buf       []byte            // 最新数据存放在 buf[off : len(buf)]	off       int               // 从&buf[off]开始读, 从&buf[len(buf)]开始写	runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune	bootstrap [64]byte          	// memory to hold first slice; helps small buffers (Printf) avoid allocation.	lastRead  readOp            // last read operation, so that Unread* can work correctly.}func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {	b.lastRead = opInvalid // 0	if b.off >= len(b.buf) { 		b.Truncate(0) //还没有写就想读,清空buf	}	for {		if free := cap(b.buf) - len(b.buf); free < MinRead {			// free的大小是总容量 - 现在占有长度			newBuf := b.buf			if b.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)		//读到尾部就返回		if e == io.EOF {			break		}		if e != nil {			return n, e		}	}	return n, nil // err is EOF, so return nil explicitly}

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

func (b *Buffer) Read(p []byte) (n int, err error) {	b.lastRead = opInvalid	if b.off >= len(b.buf) {		// Buffer is empty, reset to recover space.		b.Truncate(0)		if len(p) == 0 {			return		}		return 0, 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	if n > 0 {		b.lastRead = opRead	}	return}

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

转载于:https://my.oschina.net/yang1992/blog/502564

你可能感兴趣的文章
有孚网络副总裁吕鑫:合纵连横,云领未来—如何打造低成本混合云架构
查看>>
GNU nano 4.0 发布,简单又强大的文本编辑器
查看>>
最佳实践系列丨Docker EE 日志记录最佳实践(二)
查看>>
收集移动端HTML5/H5使用的插件
查看>>
备用电源
查看>>
安卓应用安全指南 4.2.1 创建/使用广播接收器 示例代码
查看>>
中小学生也能独立创作VR内容?睿诚华智发布面向K12的VR STEAM产品
查看>>
回文检测(包含中文与字符)
查看>>
Creating a custom creation complete effect on a Flex Alert control
查看>>
在WPF里面显示DIB图片格式的图片
查看>>
教你怎么使用Jmail发送匿名的邮件(不要身份认证)
查看>>
QQ登陆功能的实现2
查看>>
蓝桥杯 算法提高 日期计算
查看>>
SharePoint 2013 安装配置(3-2)
查看>>
Puppet数据类型中[数值类型,数组的使用] (十四)
查看>>
Hive 读取的Column值为NULL?!
查看>>
Spring中注入基本类型
查看>>
aws devops
查看>>
Android 中文API (33) —— Checkable
查看>>
脚本方式安装 IIS7
查看>>