为了账号安全,请及时绑定邮箱和手机立即绑定

io.LimitReader 读取 http.Body 时的 EOF

io.LimitReader 读取 http.Body 时的 EOF

Go
饮歌长啸 2022-06-13 10:55:26
这对某人来说可能很明显,但我需要一些帮助来看看我哪里出错了。我试图通过使用 io.LimitReader 来限制我从 http.Response.Body 读取的数据。我正在直接读取 [] 字节。但是,当我尝试这样做时,我得到了一个 EOF。下面是代码的模型。resp, err := http.Client.Do(req)if err != nil {    return nil, err}defer resp.Body.Close()lr := io.LimitReader(resp.Body, 1e+6)b := make([]byte, 1e+6)_, err := lmtdR.Read(b)if err != nil {    return nil, err}以上失败。但是,如果我这样做......resp, err := http.Client.Do(req)if err != nil {    return nil, err}defer resp.Body.Close()lr := io.LimitReader(resp.Body, 1e+6)bdy, err := ioutil.ReadAll(lr)if err != nil {    return nil, err}这行得通。所以我有一个解决方案,但我真的想知道在我给出的第一个例子中我做错了什么。任何帮助,将不胜感激。
查看完整描述

2 回答

?
狐的传说

TA贡献1804条经验 获得超3个赞

总是从文档开始。


区别在于语义:


io.Reader.Read:


~$ go doc io.Reader


package io // import "io"


type Reader interface {

    Read(p []byte) (n int, err error)

}

Reader是包装基本Read方法的接口。


Read最多将len(p)字节读入p. 它返回读取的字节数 ( 0 <= n <= len(p)) 和遇到的任何错误。即使Read返回n < len(p),它也可能在调用期间使用所有p作为暂存空间。如果某些数据可用但len(p)字节不可用,Read 通常会返回可用的数据,而不是等待更多数据。


当Read成功读取字节后遇到错误或文件结束条件时n > 0,它返回读取的字节数。它可能会从同一次调用中返回(非零)错误,或者n == 0从后续调用中返回错误(和)。这种一般情况的一个例子是,Reader在输入流的末尾返回非零字节数可能会返回 err == EOF或err == nil。下一个Read应该返回0, EOF。


io/ioutil.ReadAll:


~$ go doc ioutil.ReadAll


package ioutil // import "io/ioutil"


func ReadAll(r io.Reader) ([]byte, error)

ReadAll读取r直到出现错误或EOF返回它读取的数据。一个成功的调用返回err == nil,而不是err == EOF。因为ReadAll定义为从 src 读取 until EOF,所以它不会将EOFfromRead视为要报告的错误。


查看完整回答
反对 回复 2022-06-13
?
墨色风雨

TA贡献1853条经验 获得超6个赞

引用以下文档Reader.Read()

Read最多将 len(p) 个字节读入 p。

Read()即使源中有足够的数据,也不能保证会填充传递的切片。实现可以自由地读取更少的字节并“提前”返回,通常如果读取更多会阻塞。如果有任何机会Read()从其源读取“所有内容”,它可能会返回 EOF 以表示无法读取更多数据。这就是你所经历的。

ioutil.ReadAll()另一方面保证它继续阅读或等待,直到阅读器返回错误或报告 EOF。另请注意,如果源阅读器被读取到 EOF,ioutil.ReadAll()则不会返回 EOF 而是nil错误,因为在ReadAll().


查看完整回答
反对 回复 2022-06-13
  • 2 回答
  • 0 关注
  • 466 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号