总结:
- 当读取的字节小于数据长度时,Read一般不会返回错误,除非数据还未接收完发生了异常(例如连接中断,读取超时等)
- 当读取的字节大于等于数据长度时,Read会返回读取的字节和EOF(End Of File),表示数据已经读完了。
数据读取的几种常用方式
方式一
读取指定长度数据,实际读取的数据可能小于指定的大小
b := make([]byte, clen) n, err := resp.Body.Read(b)
需要判断err是不是EOF
方式二
读取全部数据,直到EOF或发生错误
1 b, err := ioutil.ReadAll(resp.Body)
需要判断err是不是EOF
方式三
读取全部数据到dst,直到EOF或发生错误
1 bb := bytes.NewBuffer(nil) 2 n, err := io.Copy(bb, resp.Body)
这种方式无需判断EOF错误
io.Copy与io.CopyBuffer的区别
共同点与区别
io.Copy与io.CopyBuffer实际都是copyBuffer实现的,只不过io.Copy只有源src和目的dst两个参数;而io.CopyBuffer却多了一个参数buf,io.CopyBuffer不仅会将数据拷贝到dst,另外还会拷贝到buf中。
用途
io.Copy可以把数据从一个连接拷贝到另外一个连接,可用作代理。io.CopyBuffer既可以把数据从一个连接拷贝到另外一个连接,还可以将数据保存在一个buf中,可用作缓存(即一边接收,一边发送并且缓存)。