TLDR:
my42bytes, err := ioutil.ReadAll(io.LimitReader(myReader, 42))
完整答案:
@monicuta 提到了io.ReadFull,效果很好。这里我提供另一种方法。它通过将ioutil.ReadAll 和io.LimitReader 链接在一起来工作。让我们先阅读文档:
$ go doc ioutil.ReadAll
func ReadAll(r io.Reader) ([]byte, error)
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.
$ go doc io.LimitReader
func LimitReader(r Reader, n int64) Reader
LimitReader returns a Reader that reads from r but stops with EOF after n
bytes. The underlying implementation is a *LimitedReader.
所以如果你想从myReader 获取 42 个字节,你可以这样做
import (
"io"
"io/ioutil"
)
func main() {
// myReader := ...
my42bytes, err := ioutil.ReadAll(io.LimitReader(myReader, 42))
if err != nil {
panic(err)
}
//...
}
这是io.ReadFull的等效代码
$ go doc io.ReadFull
func ReadFull(r Reader, buf []byte) (n int, err error)
ReadFull reads exactly len(buf) bytes from r into buf. It returns the number
of bytes copied and an error if fewer bytes were read. The error is EOF only
if no bytes were read. If an EOF happens after reading some but not all the
bytes, ReadFull returns ErrUnexpectedEOF. On return, n == len(buf) if and
only if err == nil. If r returns an error having read at least len(buf)
bytes, the error is dropped.
import (
"io"
)
func main() {
// myReader := ...
buf := make([]byte, 42)
_, err := io.ReadFull(myReader, buf)
if err != nil {
panic(err)
}
//...
}
与io.ReadFull相比,一个优点是您不需要手动创建buf,其中len(buf)是您要读取的字节数,然后在您传递buf作为参数时阅读
相反,您只需告诉io.LimitReader 您最多需要来自myReader 的42 个字节,然后调用ioutil.ReadAll 将它们全部读取,并将结果作为字节片返回。如果成功,则保证返回的切片长度为 42。