После вызова метода Peek исходные данные изменились - PullRequest
0 голосов
/ 07 декабря 2018
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 байтов, он также возвращает ошибку, объясняющую, почему чтение является коротким.Ошибка ErrBufferFull, если n больше размера буфера b. '

1 Ответ

0 голосов
/ 07 декабря 2018

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...