🙌
【Go】bytes.Bufferを活用
そもそも、bytes.Bufferは何なのでしょうか。
bytesのパッケージドキュメントには、
A Buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use.
と説明されています。
上記の通り、*bytes.Bufferは、Goでお馴染みインターフェースのio.Readerとio.Writerを実装しています。
aws-sdk-goを用いて、S3へ画像をアップロードするときに、byteスライスを例えば以下のように変換することがあるでしょう。
// ここではdataをバイト列と仮定
b := new(bytes.Buffer)
b.Write(data)
uploader := &s3manager.UploadInput{
// Bodyはio.Readerを受け入れる
Body: b,
以下つづく...
}
Bodyはio.Readerな必要があるため、このような場面でbytes.Bufferを活用できます。
(そうだ、bytes.Buffer関連のメソッドを簡単にまとめてみよう。)
func (b *Buffer) WriteTo(w io.Writer) (n int64, err error)
WriteToメソッドはバッファの中身が空になるかエラーが発生するまで、引数のwにデータを書き込みます。返り値のnは、書き込んだバイトの数になります。
package main
import (
"bytes"
"fmt"
"os"
)
func main() {
buf := bytes.NewBuffer([]byte("HANABI"))
// os.Stdoutを指定しているため、標準出力で「HANABI」と表示される
if _, err := buf.WriteTo(os.Stdout); err != nil {
fmt.Println(err)
}
}
func (*Buffer) Grow(n int)
Growメソッドで、バッファのサイズを上げることができます。別の割り当てをすることなしに、少なくとも引数のnバイトをバッファに書き込むことができます。読み込みが遅い場合などに指定。
package main
import (
"bytes"
"fmt"
)
func main() {
buf := new(bytes.Buffer)
buf.Grow(64)
b := buf.Bytes()
buf.Write([]byte("64 bytes or fewer"))
// output: 64 bytes or fewer
fmt.Printf("%q", b[:buf.Len()])
}
func (*Buffer) Reset
Resetメソッドは、バッファを空にします。
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBuffer([]byte("HANABI"))
fmt.Printf("string: %s len: %v\n", buf.String(), buf.Len())
buf.Reset()
fmt.Printf("string: %s len: %v", buf.String(), buf.Len())
}
func (*Buffer) Truncate(n int)
Truncateメソッドは、バッファから最初のnバイトを除く全てのバイトを破棄します。
ちなみに、内部の実装は以下のようになっています。0の場合はResetが実行されます。
func (b *Buffer) Truncate(n int) {
if n == 0 {
b.Reset()
return
}
b.lastRead = opInvalid
if n < 0 || n > b.Len() {
panic("bytes.Buffer: truncation out of range")
}
b.buf = b.buf[:b.off+n]
}
もう少しつらつらと書いていこうと思ったけど、もうこんな時間だから一旦眠ります😪
Discussion