【问题标题】:EOF error after writing HTTP response body to file [duplicate]将HTTP响应正文写入文件后出现EOF错误[重复]
【发布时间】:2019-01-29 07:14:48
【问题描述】:

我想在解析之前将 JSON 响应保存到文本文件:

req, err := http.NewRequest("POST", url, body)
req.Header.Set("Authorization", "secret_key")
req.Header.Set("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

f, err := os.Create("./response.json")
if err != nil {
    log.Fatal(err)
}
defer f.Close()
io.Copy(f, resp.Body)

var result JSONResult
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
    log.Fatal(err)
}

它成功地将 JSON 写入文件,但随后在解码步骤中失败,并出现一个错误,即 EOF。如果我在写入文件之前解析它可以解析,但是文件是空的。有人可以解释一下这里发生了什么吗?谢谢!

【问题讨论】:

    标签: go


    【解决方案1】:

    http.Response.Bodyio.ReadCloser 类型,只能读取一次(如您所见,它没有倒带方法)。

    因此,或者出于解码目的,您可以读取刚刚创建的文件。

    或者如果响应不大(或者您可以使用io.LimitReader 修剪它) - 您可以将其读入缓冲区

    (未测试,类似这些):

    f, err := os.Create("./response.json")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    
    var buf bytes.Buffer
    tee := io.TeeReader(r.Body, &buf)
    
    io.Copy(f, tee)
    
    var result JSONResult
    if err := json.NewDecoder(buf).Decode(&result); err != nil {
        log.Fatal(err)
    }
    

    参考资料:

    【讨论】:

    • 太好了,谢谢!我刚开始学习 Go,我在文档中没有看到任何解释 io.ReadCloser 只能读取一次的内容。我在哪里可以了解更多信息?
    • @Vincent 老实说,我找不到它的记录位置,但我认为这是隐含的:如果流无法倒带 - 它是只读一次。
    • @Vincent 看看golang.org/pkg/io/#Seeker 如果有东西可以倒带——那么它实现了io.Seeker(而r.Body 没有)
    • @zerkms 斯帕西博! :)
    • @Volker 我倾向于认为对于 SO 上的每个围棋问题,都有一个很好的 icza 答案:-D
    猜你喜欢
    • 2020-11-26
    • 2011-02-25
    • 2018-08-06
    • 2016-04-23
    • 2017-05-17
    • 1970-01-01
    • 2015-03-11
    • 2022-10-08
    相关资源
    最近更新 更多