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であることが保証されます。