Go の io.Reader 覚書
備忘録。
Go の io.Reader
の使い方について。
なぜ io.Reader
?
これはファイルだろうと文字列だろうと全て同じように扱えるようにするため。
標準/3rd party 問わず、文字列もしくはバイト列を受け取るようなライブラリ関数の引数は string
でも []byte
でもなく io.Reader
を受け取るようになっていることが多い。(([]byte
も受け取れるようになっているものはあるが、string
を受け取るものはまず見かけない))
自分でバイト列を受け取るライブラリを作る場合も io.Reader
を受け取るようにし、テストコードなどでは []byte
や string
から io.Reader
に変換して入力データを作ればいい。入力データが []byte
の場合は bytes.NewReader
を、string
の場合は strings.NewReader
を使う。
ユースケース
(随時追記予定)
N バイトずつ読み込む
io.ReadFull
を使う。残りが0バイトの時は io.EOF
を返すが、N バイト未満だった場合は io.ErrUnexpectedEOF
を返すのでちょっと注意が必要。
以下は文字列を最大8バイトずつの [][]byte
に分割する例。
func main() { r := strings.NewReader("01234567890123456789") result := make([][]byte, 0) for i := 0; ; i++ { buf := make([]byte, 8) n, err := io.ReadFull(r, buf) if err == io.EOF { break } else if err == nil { result = append(result, buf) } else if err == io.ErrUnexpectedEOF { dst := make([]byte, n) copy(dst, buf) result = append(result, dst) } else { log.Fatal(err) } } fmt.Printf("%s\n", result) }