如何在Go语言中使用HTTP响应方法Read?

3

我很久没有接触过go语言了,好像忘记了如何阅读文档。

如果我想进行如下的get请求...

resp, err := http.Get("https://example.com")

我发现响应具有Body属性,其类型为io.ReadCloserhttps://golang.org/pkg/io/#ReadCloser)。我看到ReadCloserReaderCloser接口的结合体。

当我查看Reader接口时,我发现它有一个Read方法,用于读取字节到p中(https://golang.org/pkg/io/#Reader)。

简而言之,http Response包含了一个io.ReadCloser接口的,该接口本身包含了一个Reader接口和一个Read方法。

当我尝试这样做时,我期望将响应字节读取到HTML中,但是我什么都没有看到...

var html []byte
num, err := resp.Body.Read(html)
fmt.Println("\n\thtml: ", html)
fmt.Printf("\n\tnum: %v, err: %v\n", num, err)

输出:

html:  []
num: 0, err: <nil>

这里我错过了什么?

你需要分配空间来读取内容。你只提供了一个空的切片,所以 Read 无法“读取”任何东西。 - JimB
1
读取操作将 html 中最多 len(html) 字节的数据读入,这里是零。 - Sarath Sadasivan Pillai
3个回答

8
简短回答:您正在传递长度为“0”的片段html,而Read会将最多len(html)字节读入html。
以下是来自https://golang.org/pkg/io/#Reader的代码片段:

Read将最多len(p)字节读入p。 它返回读取的字节数(0 <= n <= len(p))和任何遇到的错误。 即使Read返回n 现在,您可以使用ioutil并更新代码如下:

body, err := ioutil.ReadAll(resp.Body)

代码

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    resp, err := http.Get("http://httpbin.org/ip")
    if err != nil {
        fmt.Println("Error making request", err.Error())
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Error reading response", err.Error())
        return
    }
    fmt.Println("Response\n", string(body))
}

这里是玩耍的链接,在go playground中,HTTP请求不起作用,这是一种安全预防措施,因此您可以在自己的计算机上测试此功能。


1
尝试使用“io/ioutil”包:
import "io/ioutil"
...
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(body)

0

你缺少一个好的帮手和朋友 ReadAll()

你的代码应该像这样:

import "io/ioutil"

resp, err := http.Get("https://example.com")
// check err

defer resp.Body.Close() // we have to close Body if we want to reuse the connection

html, err := ioutil.ReadAll(resp.Body)
// check err

fmt.Println(string(html))

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