package main
import (
"bufio"
"io"
"golang.org/x/net/html/charset"
"golang.org/x/text/encoding"
"net/http"
"fmt"
"golang.org/x/text/transform"
"io/ioutil"
)
// main
func main() {
resp, err := http.Get("http://www.baidu.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Println("Error: status code", resp.StatusCode)
return
}
e := determineEncoding(resp.Body)
utf8Reader := transform.NewReader(resp.Body, e.NewDecoder())
all, err := ioutil.ReadAll(utf8Reader)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", all)
}
// determine
func determineEncoding(r io.Reader) encoding.Encoding {
reader := bufio.NewReader(r)
// The start position was not correct
bytes, err := reader.Peek(1024)
if err != nil {
panic(err)
}
e, _, _ := charset.DetermineEncoding(bytes, "")
return e
}
结果不是正确的数据。起始位置不为零。
如文档所述,“ Peek返回下n个字节,而不会提高阅读器。字节在下一个读取调用时停止有效。如果Peek返回的字节数少于n个字节,则它还会返回一个错误,解释为什么读取短。如果n大于b的缓冲区大小,则错误为ErrBufferFull。'
答案 0 :(得分:1)
Peek返回下一个n个字节,而不会使阅读器前进。
这是指*bufio.Reader
,而不是基础读者。如有必要,缓冲的读取器 将从基础读取器中读取。否则它将如何返回字节?
在您的情况下,您必须在调用determineEncoding
之后直接停止使用响应正文,而改用* bufio.Reader。
例如:
func determineEncoding(r *bufio.Reader) encoding.Encoding {
bytes, err := r.Peek(1024)
// as before
}
func main() {
// as before
defer resp.Body.Close()
r := bufio.NewReader(resp.Body)
e := determineEncoding(r)
utf8Reader := transform.NewReader(r, e.NewDecoder())
// as before
}