Golang 中的 Bytes 包詳解之 Bytes.Buffer

Golang 中的 bytes 包是其中一個 IO 操作標(biāo)準(zhǔn)庫,實現(xiàn)了對字節(jié)切片([]byte)的操作,提供了類似于 strings 包的功能。本文先講解一下 bytes 包中的結(jié)構(gòu)體 bytes.Buffer。
bytes.Buffer
bytes.Buffer 實現(xiàn)了 io.Writer、io.Reader、io.ByteScanner、io.RuneScanner、io.WriterTo、io.ByteWriter 和 io.ReaderFrom 等接口,可以很方便地實現(xiàn)對字節(jié)數(shù)據(jù)的讀寫和操作。主要特點(diǎn)是提供了一個緩沖區(qū),可以在內(nèi)存中動態(tài)分配緩沖區(qū),以高效地寫入和讀取字節(jié)數(shù)據(jù)。在處理數(shù)據(jù)時,特別是數(shù)據(jù)拼接操作時,效率往往比直接使用字符串拼接要高很多。結(jié)構(gòu)體定義和對應(yīng)的方法如下:
type Buffer struct {
buf []byte // contents are the bytes buf[off : len(buf)]
off int // read at &buf[off], write at &buf[len(buf)]
lastRead readOp // last read operation, so that Unread* can work correctly.
}其中,buf 保存了實際的字節(jié)緩存,off 表示下一個讀寫操作的偏移量,lastRead 表示最后一次讀取操作的類型和大小。
bytes.Buffer 提供的主要方法包括:
- ReadFrom,從 io.Reader 中讀取數(shù)據(jù),并寫入到緩沖區(qū)中。
- WriteTo,從緩沖區(qū)中讀取數(shù)據(jù),并寫入到 io.Writer 中。
- WriteByte、WriteRune、WriteString,分別用于將單個字節(jié)、Unicode 字符和字符串寫入緩沖區(qū)中。
- ReadByte、ReadRune、ReadString,分別用于從緩沖區(qū)中讀取單個字節(jié)、Unicode 字符和字符串。
- Bytes、String,返回緩沖區(qū)中的字節(jié)切片和字符串。
- Reset,用于重置緩沖區(qū),將其擴(kuò)容為默認(rèn)大小(64 字節(jié))。
其他方法就不一一說明了,最好自己去看去使用去體會。
使用示例
簡單使用示例如下:
package main
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os"
)
func main() {
var buf bytes.Buffer
// 寫入一個字節(jié)
err := buf.WriteByte('a')
if err != nil {
fmt.Println(err)
return
}
// 寫入一個字符串
_, err = buf.WriteString("b")
if err != nil {
fmt.Println(err)
return
}
// 寫入一個無符號整數(shù)
var u uint32 = 12345
err = binary.Write(&buf, binary.LittleEndian, u)
if err != nil {
fmt.Println(err)
return
}
// 讀取一個字節(jié)
b, err := buf.ReadByte()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(b)) // a
// 讀取一個字符串
s, err := buf.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
fmt.Println(s) // b
// 讀取無符號整數(shù)
var u2 uint32
err = binary.Read(&buf, binary.LittleEndian, &u2)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u2) // 12345
// 拷貝到標(biāo)準(zhǔn)輸出中
_, err = io.Copy(os.Stdout, &buf)
if err != nil {
fmt.Println(err)
return
}
// 讀取到 []byte 中,并以字符串輸出
data, err := io.ReadAll(&buf)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(data))
}首先創(chuàng)建了一個 bytes.Buffer 對象 buf,分別使用 WriteByte、WriteString 和 binary.Write 方法向緩沖區(qū)中寫入一個字節(jié)、一個字符串和一個無符號整數(shù)。然后分別使用 ReadByte、ReadString 和 binary.Read 方法從緩沖區(qū)中讀取了一個字節(jié)、一個字符串和一個無符號整數(shù)。接下來使用 io.Copy 方法和 os.Stdout 將緩沖區(qū)中的數(shù)據(jù)拷貝到標(biāo)準(zhǔn)輸出中,最后使用 io.ReadAll 方法將緩沖區(qū)中的所有數(shù)據(jù)讀取到一個字節(jié)切片中,并轉(zhuǎn)換為一個字符串。
小結(jié)
使用 bytes.Buffer 可以方便高效地處理字節(jié)數(shù)據(jù),避免頻繁地對底層的字節(jié)數(shù)組進(jìn)行擴(kuò)容和復(fù)制,從而提高性能。





































