简而言之:
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() {
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() {
buf := make([]byte, 42)
_, err := io.ReadFull(myReader, buf)
if err != nil {
panic(err)
}
}
与
io.ReadFull
相比,使用
io.LimitReader
的一个优点是您无需手动创建
buf
,其中
len(buf)
是您想要读取的字节数,然后在 Read 时将
buf
作为参数传递。
相反,您只需告诉
io.LimitReader
您最多从
myReader
中读取 42 字节,并调用
ioutil.ReadAll
读取它们所有,将结果作为字节切片返回。如果成功,返回的切片长度保证为 42。
io.ReadAtLeast(reader, p, len(p))
同时,在使用io.ReadFull时,你应该先定义p,并使其长度等于你想读取的字节数,但在使用io.ReadAtLeast时,p的长度可以随意设置,只要它比你想读取的字节数大或相等就行。 - sepehr