如何使用 Golang 的 net/http 包读取流响应正文?

Posted

技术标签:

【中文标题】如何使用 Golang 的 net/http 包读取流响应正文?【英文标题】:How do I read a streaming response body using Golang's net/http package? 【发布时间】:2014-04-02 05:50:55 【问题描述】:

我正在尝试连接到对 json 数据进行 http 流式传输的端点。我想知道如何使用 Go 的 net/http 包执行基本请求并读取响应。目前,我只能在连接关闭时读取响应。

resp, err := http.Get("localhost:8080/stream")
if err != nil 
    ...

...
// perform work while connected and getting data

任何见解将不胜感激!

谢谢!

-RC

【问题讨论】:

您看到this answer 有帮助吗? 该代码将对流进行操作。如果您没有按预期收到它,那是因为服务器发送它的方式。我已经用这个模型解析了很多 GB 的响应。 【参考方案1】:

Eve Freeman 提供的答案是读取 json 数据的正确方法。读取任何类型的数据,可以使用下面的方法:

resp, err := http.Get("http://localhost:3000/stream")
...

reader := bufio.NewReader(resp.Body)
for 
    line, err := reader.ReadBytes('\n')
    ...

    log.Println(string(line))

【讨论】:

但是如何在那个 []byte 上检测到 EOF? EOF 返回错误 现在使用这些块/行如何直接将其写入文件。表示如何使用流而不是整个文件进行写入。 ?【参考方案2】:

进行流式 JSON 解析的方法是使用解码器:

json.NewDecoder(resp.Body).Decode(&yourStuff)

对于返回一堆对象的流式 API(例如 Twitter),使用此模型和内置的 encoding/json API 应该可以很好地进行流式传输。但是,如果它是一个大型响应,其中您有一个包含 10MB 内容的巨型数组的对象,您可能需要编写自己的解码器来拉出这些内部部分并返回它们。我编写的库遇到了这个问题。

【讨论】:

感谢您的回答!我设法通过创建一个 bufio.Reader 并在 resp.Body 上调用 ReadBytes() 来使其工作。 Eve,哪里有关于最大 10MB 的文档?我需要信息 这不是一个最大值,它只是解析器的工作方式,一次对象。 有没有办法在响应写入完成时进行监听?

以上是关于如何使用 Golang 的 net/http 包读取流响应正文?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Golang net/http 服务器接收上传的文件?

如何在 golang net/http 中使用 Transport 添加头信息

golang如何创建反向代理

Golang pprof详解

如何在 Golang 中使用 HTTP/2 写入/读取/发送数据帧?

Golang net/http 请求处理流程分析