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.
Итак, если вы хотите получить 42 байта из myReader
, вы делаете это
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
, что вам нужно не более 42 байтов из myReader
, и вызываете ioutil.ReadAll
, чтобы прочитать их все, возвращая результат в виде фрагмента байтов. В случае успеха возвращаемый фрагмент гарантированно будет иметь длину 42.
person
navigaid
schedule
15.05.2019