我正在寻找用于获取url的go代码,并且在大多数情况下,这是用于在go上获取url的代码:
func main() {
for _, url := range os.Args[1:] {
resp, err := http.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
os.Exit(1)
}
b, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
os.Exit(1)
}
fmt.Printf("%s", b)
}
}
我的问题为何在这里需要resp.Body.Close()并完全做到这一点呢?
答案 0 :(得分:2)
如果您浏览http文档https://golang.org/pkg/net/http/
用于响应的Get方法是响应
func (c *Client) Get(url string) (resp *Response, err error)
在响应源中:
// Body represents the response body.
//
// The response body is streamed on demand as the Body field
// is read. If the network connection fails or the server
// terminates the response, Body.Read calls return an error.
//
// The http Client and Transport guarantee that Body is always
// non-nil, even on responses without a body or responses with
// a zero-length body. It is the caller's responsibility to
// close Body. The default HTTP client's Transport may not
// reuse HTTP/1.x "keep-alive" TCP connections if the Body is
// not read to completion and closed.
//
// The Body is automatically dechunked if the server replied
// with a "chunked" Transfer-Encoding.
Body io.ReadCloser
因此Close()整理了用于获取主体的资源
如果不这样做,响应(resp)将无法执行“保持活动”,我想响应中的某些资源可能无法回收< / p>
答案 1 :(得分:1)
当您使用ioutil.ReadAll
时,您正在调用Read
的{{1}}函数。这将设置一个“寻找者”,该行为将读取response.Body
的内容并返回包含该内容的缓冲区。 response.Body
Close
时,您将“搜索”位置重置为零,并将tcp连接返回到连接池。这样可以确保您将来可能对此响应进行的任何读取都将从零开始,而不是说response.Body
,并确保没有等待读取的未返回的tcp连接。