Golang request.Body.Close() returns 一个空文档
Golang request.Body.Close() returns an empty Document
我在 2 个不同的包中有 2 个方法,其中 func B() 使用 url 读取网页和 returns *html.Tokenizer。但问题是,它工作正常只有当我评论 defer r.Body.Close() 时,如果我启用它,这个从 func B 返回的文档是空的。
如果两个函数合并为一个函数,它也可以工作。但我需要 2 个不同的包装。
关于我在这里缺少什么的任何建议或想法? res.Body 不应该关闭吗?
func (s ParserService) A(u string) (*domain.Result, error) {
doc, err := s.B("https://www.google.com/")
if err != nil {
fmt.Println(err.Error())
}
for tokenType := doc.Next(); tokenType != html.ErrorToken; {
token := doc.Token()
fmt.Println(token)
tokenType = doc.Next()
}
}
func (c Downloader) B(url string) (*html.Tokenizer, error) {
r, err := c.httpClient.Get(url)
if err != nil {
return nil, err
}
// defer r.Body.Close()
doc := html.NewTokenizer(r.Body)
return doc, nil
}
tl;博士
html.Tokenier
的 Next
方法直接从 reader 中读取。在通过分词器完成处理之前不要关闭正文。在您的示例中,您应该在同一个函数中执行 HTTP 请求并标记正文,然后您可以取消对延迟关闭的注释。
详情
html.Tokenizer
接受一个 io.Reader
,分词器将从中读取,直到收到 io.EOF
错误。此“错误”表示没有任何内容可读,分词器源已完成。
http.Request.Body
是 io.ReadCloser
,它是 io.Reader
和 io.Closer
的组合。调用 Close
后发生的事情是特定于实现的,但是对于 http.Request.Body,在调用关闭后无法从 reader 读取更多字节。
您的问题最终是由于过早关闭http.Request.Body
(io.ReadCloser
)造成的。
我在 2 个不同的包中有 2 个方法,其中 func B() 使用 url 读取网页和 returns *html.Tokenizer。但问题是,它工作正常只有当我评论 defer r.Body.Close() 时,如果我启用它,这个从 func B 返回的文档是空的。
如果两个函数合并为一个函数,它也可以工作。但我需要 2 个不同的包装。
关于我在这里缺少什么的任何建议或想法? res.Body 不应该关闭吗?
func (s ParserService) A(u string) (*domain.Result, error) {
doc, err := s.B("https://www.google.com/")
if err != nil {
fmt.Println(err.Error())
}
for tokenType := doc.Next(); tokenType != html.ErrorToken; {
token := doc.Token()
fmt.Println(token)
tokenType = doc.Next()
}
}
func (c Downloader) B(url string) (*html.Tokenizer, error) {
r, err := c.httpClient.Get(url)
if err != nil {
return nil, err
}
// defer r.Body.Close()
doc := html.NewTokenizer(r.Body)
return doc, nil
}
tl;博士
html.Tokenier
的 Next
方法直接从 reader 中读取。在通过分词器完成处理之前不要关闭正文。在您的示例中,您应该在同一个函数中执行 HTTP 请求并标记正文,然后您可以取消对延迟关闭的注释。
详情
html.Tokenizer
接受一个 io.Reader
,分词器将从中读取,直到收到 io.EOF
错误。此“错误”表示没有任何内容可读,分词器源已完成。
http.Request.Body
是 io.ReadCloser
,它是 io.Reader
和 io.Closer
的组合。调用 Close
后发生的事情是特定于实现的,但是对于 http.Request.Body,在调用关闭后无法从 reader 读取更多字节。
您的问题最终是由于过早关闭http.Request.Body
(io.ReadCloser
)造成的。