英文:
How to use http Response method Read in go?
问题
好的,我将为你翻译以下内容:
"我已经有一段时间没有使用Go语言了,似乎忘记了如何阅读文档。
如果我像这样进行一个GET请求...
resp, err := http.Get("https://example.com")
然后我发现响应中有一个Body
,它是一个io.ReadCloser
类型的对象(https://golang.org/pkg/io/#ReadCloser)。我看到ReadCloser
是Reader
和Closer
的接口。
当我查看Reader
接口时,我发现它有一个Read
方法,用于将字节读入p
(https://golang.org/pkg/io/#Reader)。
总结一下,http Response
有一个Body
,它是一个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>
我在这里漏掉了什么?"
英文:
It's been a while since I dealt with go and I seem to have forgotten how to read the docs.
If I do a get request like this...
resp, err := http.Get("https://example.com")
I then see that the response has a Body
that is of an io.ReadCloser
type (https://golang.org/pkg/io/#ReadCloser). I see the ReadCloser is an interface to Reader
and Closer
.
When I look at the Reader
interface I see it has a Read
method that reads bytes into p
(https://golang.org/pkg/io/#Reader).
To recap, the http Response
has a body which is a io.ReadCloser
Interface which itself contains a Reader
interface which has a Read
method.
When I try this I would expect to Read
the response bytes into HTML, but I see nothing...
var html []byte
num, err := resp.Body.Read(html)
fmt.Println("\n\thtml: ", html)
fmt.Printf("\n\tnum: %v, err: %v\n", num, err)
Output:
html: []
num: 0, err: <nil>
What am I missing here?
答案1
得分: 8
简短回答:您正在传递一个切片 html
,其中 html
的长度将为 '0',而 Read
函数会读取 len(html)
字节到 html
中。
以下是代码的翻译部分:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("http://httpbin.org/ip")
if err != nil {
fmt.Println("发生请求错误", err.Error())
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取响应错误", err.Error())
return
}
fmt.Println("响应\n", string(body))
}
在这里是 链接,在 Go Playground 中无法进行 HTTP 请求,这是一种安全预防措施,所以您可以在自己的计算机上测试这段代码。
英文:
short answer: You are passing a slice html
where its len would be '0' and Read reads up to len(html)
bytes into html
Here is snippet from https://golang.org/pkg/io/#Reader
> Read reads up to len(p) bytes into p. It returns the number of bytes
> read (0 <= n <= len(p)) and any error encountered. Even if Read
> returns n < len(p), it may use all of p as scratch space during the
> call. If some data is available but not len(p) bytes, Read
> conventionally returns what is available instead of waiting for more.
Now what you may do use ioutil
and update the code as
body, err := ioutil.ReadAll(resp.Body)
Code
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))
}
Here is play link, in go playground HTTP requests won't work it is a security precaution so you may test this in your machine
答案2
得分: 1
请尝试使用"io/ioutil"包:
import "io/ioutil"
...
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(body))
英文:
Try to use "io/ioutil" package:
import "io/ioutil"
...
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(body)
答案3
得分: 0
你缺少一个好的助手和朋友ReadAll()
你的代码应该像这样:
import "io/ioutil"
resp, err := http.Get("https://example.com")
// 检查错误
defer resp.Body.Close() // 如果我们想重用连接,我们必须关闭Body
html, err := ioutil.ReadAll(resp.Body)
// 检查错误
fmt.Println(string(html))
英文:
You're missing a good helper and friend ReadAll()
Your code should looks like this:
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))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论