strings.Readerを触ってみた。
目次
NewReader
strings.Readerのポインタを生成する。
reader := strings.NewReader("abcdef") fmt.Printf("%T %v\n", reader, reader) // *strings.Reader &{abcdef 0 -1}
ちなみにここで生成されるstrings.Readerはio.Reader
というinterfaceの定義を満たしているので、io.Readerとして扱うことができる。
type Reader interface { Read(p []byte) (n int, err error) }
strings.Readerはこんな感じのパラメータを持っている。
type Reader struct { s string i int64 // current reading index prevRune int // index of previous rune; or < 0 }
Read
現在のリードインデックスの位置から終端までの文字列をリードする。
var n int var err error reader := strings.NewReader("abcdef") buf := make([]byte, reader.Size()) n, err = reader.Read(buf) fmt.Println(string(buf), len(buf), n, err) // abcdef 6 6 <nil>
- 引数で渡している
buf
にリードした文字列が格納される。 - 戻り値としてリードした文字数とエラーの内容を返す。
- もう一回Readを呼ぶと
err
にio.EOF
が返ってくる。
ReadAt
指定したリードインデックスから終端までの文字列をリードする。
var n int var err error reader := strings.NewReader("0123456") buf := make([]byte, reader.Size()) n, err = reader.ReadAt(buf, 2) fmt.Println(string(buf), len(buf), n, err) // 23456 7 5 EOF
- (なぜか)Readと違ってリードして終端までいったらすぐにEOFを返す。
ReadByte
1バイトずつリードする。
var b byte var err error reader := strings.NewReader("12") b, err = reader.ReadByte() fmt.Println(string(b), err) // 1 <nil> b, err = reader.ReadByte() fmt.Println(string(b), err) // 2 <nil> b, err = reader.ReadByte() fmt.Println(string(b), err) // EOF
Reset
リーダーが内部に持つ文字列を初期化する。
var b byte var err error reader := strings.NewReader("12") reader.Reset("ab") b, err = reader.ReadByte() fmt.Println(string(b), err) // a <nil> b, err = reader.ReadByte() fmt.Println(string(b), err) // b <nil>
- 引数で受け取った文字列で内部で新しくstrings.Readを作っている。
Len/Size
var n int var err error reader := strings.NewReader("abcdef") fmt.Printf("%T %v\n", reader, reader) // *strings.Reader &{abcdef 0 -1} buf := make([]byte, reader.Size()) fmt.Println(reader.Len(), reader.Size()) // 6 6 n, err = reader.Read(buf) fmt.Println(string(buf), len(buf), n, err) // abcdef 6 6 <nil> fmt.Println(reader.Len(), reader.Size()) // 0 6 n, err = reader.Read(buf) fmt.Println(string(buf), len(buf), n, err) // abcdef 6 0 EOF
- Sizeはreaderが保持している文字列全体のサイズ。常に同じ値を返す。
- Lenは現在のリードインデックスから終端までのサイズ。
Seek
リードインデクスの位置を操作する。
var b byte var err error reader := strings.NewReader("012345") reader.Seek(1, io.SeekStart) b, err = reader.ReadByte() fmt.Println(string(b), err) // 1 <nil> reader.Seek(1, io.SeekCurrent) b, err = reader.ReadByte() fmt.Println(string(b), err) // 3 <nil> reader.Seek(-1, io.SeekEnd) b, err = reader.ReadByte() fmt.Println(string(b), err) // 5 <nil>
- 他の言語でもよくあるseek関数と同じようなもの。
io.SeekEnd
を使うときはリードインデックスはマイナス値で指定する。