Я новичок в Golang.
Я пытаюсь понять, как использовать ioutil.ReadAll (не HTTP-ответ). Согласно исходному коду (и документам):
// ReadAll reads from r until an error or EOF and returns the data it read.
// A successful call returns err == nil, not err == EOF. Because ReadAll is
// defined to read from src until EOF, it does not treat an EOF from Read
// as an error to be reported.
func ReadAll(r io.Reader) ([]byte, error) {
return readAll(r, bytes.MinRead)
}
Я реализовал io.Reader здесь в этом примере (также здесь на Go Playground):
// go version go1.13.5 darwin/amd64
package main
import (
"bytes"
"fmt"
"io/ioutil"
)
// Thing contains a body
type Thing struct {
Body []byte
}
// Read reads from body into p
func (t Thing) Read(dst []byte) (n int, err error) {
// Note: bytes.Reader does return io.EOF
// https://golang.org/src/bytes/reader.go?s=1154:1204#L30
reader := bytes.NewReader(t.Body)
return reader.Read(dst)
}
func main() {
fmt.Println("Testing bytes")
thing := new(Thing)
thing.Body = []byte("Hello World")
fmt.Println("thing.Body:", string(thing.Body))
// This works
buf := make([]byte, len(thing.Body))
n, err := thing.Read(buf)
fmt.Println("Amount read:", n)
if err != nil {
fmt.Println("Error: ", err)
}
fmt.Println("buf:", string(buf))
// ReadAll runs forever....why?
buf2, err := ioutil.ReadAll(thing)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println("buf2:", buf2)
}
Выше реализация Read работает нормально. Он просто вызывает bytes.NewReader () и читает из него. Однако при использовании ioutil.ReadAll в структуре он работает вечно (время ожидания), и я не понимаю, почему. Первоначально я думал, что, возможно, там не было EOF, но считыватель байтов исходный код возвращает здесь io.EOF:
// Read implements the io.Reader interface.
func (r *Reader) Read(b []byte) (n int, err error) {
if r.i >= int64(len(r.s)) {
return 0, io.EOF
}
r.prevRune = -1
n = copy(b, r.s[r.i:])
r.i += int64(n)
return
}
Я видел другие реализации этого на Тела ответа http, где они явно должны закрыть тело после прочтения, но я не вижу метода в байтовом ридере, чтобы закрыть это.
Может кто-нибудь помочь мне понять, что происходит в этом случае? Заранее спасибо.