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

24

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

resp, err := http.Get("localhost:8080/stream")
if err != nil {
    ...
}
...
// perform work while connected and getting data
任何意见都将不胜感激!
谢谢!
-RC

你看到这个答案了吗?它有帮助吗? - Ray Toal
那段代码将在一个流上运行。如果你没有在预期的时候得到它,那是因为服务器发送数据的方式。我已经使用这个模型解析了许多GB的响应。 - Dustin
2个回答

47

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? - jsgoecke
5
EOF 被返回,伴随着一个错误。 - ciscogambo
现在使用这些代码块/行,我如何直接将其写入文件。也就是说,如何使用流而不是整个文件进行写入? - Amulya Kashyap

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

Decoder:

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

对于一个流式API,如果有一堆对象返回(比如Twitter),那么使用这个模型和内置的encoding/json API应该是很好的。但如果它是一个大响应,其中一个对象有一个包含10MB内容的巨大数组,你可能需要编写自己的解码器来提取这些内部片段并返回它们。我在一个我写的库中遇到了这个问题。


谢谢你的回答!我通过创建bufio.Reader并在resp.Body上调用ReadBytes()来使它工作。 - chourobin
Eve,10MB以内的文档在哪里?我需要信息。 - KingRider
这不是最大值,而是解析器一次处理一个对象的方式。 - Eve Freeman
有没有一种方法可以监听响应何时完成写入? - Alexander Mills

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接