我是 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/amd64package mainimport ( "bytes" "fmt" "io/ioutil")// Thing contains a bodytype Thing struct { Body []byte}// Read reads from body into pfunc (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)}上面,读取实现工作正常。它只是调用 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 响应主体上看到了其他实现,他们在阅读主体后明确地必须关闭主体,但我没有看到字节阅读器上的任何方法来关闭它。有人可以帮助我了解在这种情况下发生了什么吗?提前致谢。
1 回答
潇湘沐
TA贡献1816条经验 获得超6个赞
bytes.Reader每次Thing.Read()调用时,您都在创建一个新的。每次获得相同的 11 个字节时,ReadAll()都会继续调用您的函数。Thing.Read()
根据您的评论,我认为您只想创建一次,例如,在“构造函数”中,您不需要存储Body它,因为它存储在Bytes.Reader.
type Thing struct {
r io.Reader
}
func NewThing(s string) (t Thing) {
t.r = bytes.NewReader([]byte(s))
return
}
func (t Thing) Read(dst []byte) (n int, err error) {
return t.r.Read(dst)
}
但那Thing只是一个io.Reader没有目的的包装。你也可以直接使用`io.Reader'。
buf2, err := ioutil.ReadAll(bytes.NewReader([]byte("Hello World")))
- 1 回答
- 0 关注
- 89 浏览
添加回答
举报
0/150
提交
取消