创建缓冲区
方法签名:
func bytes.NewBufferString(s string) *bytes.Buffer
func bytes.NewBuffer(buf []byte) *bytes.Buffer
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf1 := bytes.NewBufferString("hello world")
buf2 := bytes.NewBuffer([]byte("hello world"))
buf3 := bytes.NewBuffer([]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'})
fmt.Println(buf1.String(), buf2.String(), buf3.String())
}
WriteXx
系列方法
用于将内容写入缓冲区的尾部,或者写入一个实现了 io.Writer
的结构体,这里只适合于 WriteTo
方法。
Write
写入 []byte
方法签名:func (b *bytes.Buffer) Write(p []byte) (n int, err error)
go
package main
import (
"bytes"
"fmt"
)
func main() {
s := []byte(" world")
buf := bytes.NewBufferString("hello")
buf.Write(s)
fmt.Println(buf.String())
}
WriteString
写入 string
方法签名:func (b *bytes.Buffer) WriteString(s string) (n int, err error)
go
package main
import (
"bytes"
"fmt"
)
func main() {
s := " world"
buf := bytes.NewBufferString("hello")
buf.WriteString(s)
fmt.Println(buf.String())
}
WriteByte
写入 byte
方法签名:func (b *bytes.Buffer) WriteByte(c byte) error
go
package main
import (
"bytes"
"fmt"
)
func main() {
var s byte = '?'
buf := bytes.NewBufferString("hello")
buf.WriteByte(s)
fmt.Println(buf.String()) // Output: hello?
}
WriteRune
写入 rune
方法签名: func (b *bytes.Buffer) WriteRune(r rune) (n int, err error)
rune
类型的主要作用是提供一种方便的方式来处理Unicode字符集中的字符,尤其是那些不能由一个字节表示的字符。
go
package main
import (
"bytes"
"fmt"
)
func main() {
var s rune = '中'
buf := bytes.NewBufferString("hello")
buf.WriteRune(s)
fmt.Println(buf.String()) // Output: hello中
}
WriteTo
写入 io.Writer
方法签名:func (b *bytes.Buffer) WriteTo(w io.Writer) (n int64, err error)
go
package main
import (
"bytes"
"fmt"
"os"
)
func main() {
file, _ := os.Create("test.txt")
defer file.Close()
buf := bytes.NewBufferString("Hello, world!")
// Write the buffer to the file
buf.WriteTo(file)
// Alternatively, you can write the buffer to the file using the Write method
file.Write(buf.Bytes())
// Or you can use the Fprintf method to write the buffer to the file
fmt.Fprintf(file, buf.String())
fmt.Println("File written successfully")
}
ReadXx
系列方法
ReadXx
系列方法用于从 Buffer 中读取内容,也可以从实现了 io.Reader
的结构体中读取内容,仅适用于 ReadFrom
方法。
Read
读取 []byte
方法签名:func (b *bytes.Buffer) Read(p []byte) (n int, err error)
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBufferString("Hello, world!")
s1 := make([]byte, 3)
n, _ := buf.Read(s1)
fmt.Println(string(s1), buf.String(), n) // Output: Hel lo, world! 3
s2 := make([]byte, 7)
n2, _ := buf.Read(s2)
fmt.Println(string(s2), buf.String(), n2) // Output: lo, wor ld! 7
}
ReadByte
读取 byte
方法签名:func (b *bytes.Buffer) ReadByte() (byte, error)
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBufferString("Hello, world!")
b, _ := buf.ReadByte()
fmt.Printf("The first byte is: %c\n", b) // Output: The first byte is: H
b2, _ := buf.ReadByte()
fmt.Printf("The second byte is: %c\n", b2) // Output: The second byte is: e
}
ReadBytes
/ ReadString
按分隔符读取 []byte
方法签名:
func (b *bytes.Buffer) ReadBytes(delim byte) (line []byte, err error)
func (b *bytes.Buffer) ReadString(delim byte) (line string, err error)
ReadBytes
和 ReadString
功能一样,区别在于返回的一个是字节切片,一个是字符串。
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBufferString("Hello, world!")
b, _ := buf.ReadBytes('o')
// Output: 读取的内容是:Hello,剩下的内容是:, world!
fmt.Printf("读取的内容是:%s,剩下的内容是:%s\n", b, buf.String())
b2, _ := buf.ReadBytes('o')
// Output: 读取的内容是:, wo,剩下的内容是:rld!
fmt.Printf("读取的内容是:%s,剩下的内容是:%s", b2, buf.String())
}
ReadRune
读取 rune
方法签名:func (b *bytes.Buffer) ReadRune() (r rune, size int, err error)
go
package main
import (
"bytes"
"fmt"
"reflect"
)
func main() {
buf := bytes.NewBufferString("你好,世界")
r, _, _ := buf.ReadRune()
fmt.Printf("The first rune is: %c\n", r) // Output: The first rune is: 你
r2, _, _ := buf.ReadRune()
fmt.Printf("The second byte is: %c\n", r2) // Output: The second byte is: 好
fmt.Println(isRune(r), isRune2(r2)) // Output: true true
}
func isRune(r rune) bool {
return reflect.TypeOf(r) == reflect.TypeOf(rune(0))
}
func isRune2(v interface{}) bool {
var isRune bool
switch v.(type) {
case rune:
isRune = true
default:
isRune = false
}
return isRune
}
ReadFrom
从 io.Reader
中读取
方法签名:func (b *bytes.Buffer) ReadFrom(r io.Reader) (n int64, err error)
go
package main
import (
"bytes"
"fmt"
"os"
)
func main() {
file, _ := os.Open("test.txt")
buf := bytes.NewBufferString("内容:")
buf.ReadFrom(file)
fmt.Println(buf.String()) // Output: 内容:Hello, world!
}
取消最近一次读取
使用 UnreadByte
(其方法签名为:func (b *bytes.Buffer) UnreadByte() error
)和 UnreadRune
(基方法签名为:func (b *bytes.Buffer) UnreadRune() error
)来取消最近一次成功读取的最后一个 byte
或 rune
内容。
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBufferString("Hello, world!")
s1 := make([]byte, 3)
buf.Read(s1)
fmt.Println(buf.String()) // Output: lo, world!
buf.UnreadByte()
fmt.Println(buf.String()) // Output: llo, world!
buf2 := bytes.NewBufferString("你好,世界")
buf2.ReadRune()
buf2.ReadRune()
buf2.ReadRune()
fmt.Println(buf2.String()) // Output: 世界
buf2.UnreadRune()
fmt.Println(buf2.String()) // Output: ,世界
}
内容截取
使用 Truncate
(方法签名:func (b *bytes.Buffer) Truncate(n int)
)可以截取指定前 n
个字节数据。
使用 Next
(方法签名:func (b *bytes.Buffer) Next(n int) []byte
)相反,可以截取指定 n
个字节后面的数据,并返回前 n
个字节数据。
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBufferString("Hello, world!")
buf.Truncate(3)
fmt.Println(buf.String()) // Output: Hel
buf2 := bytes.NewBufferString("Hello, world!")
n := buf2.Next(3)
fmt.Println(string(n)) // Output: Hel
fmt.Println(buf2.String()) // Output: lo, world!
}
清空 Buffer
使用 Reset
(方法签名:func (b *bytes.Buffer) Reset()
)来清空 Buffer。
go
package main
import (
"bytes"
"fmt"
)
func main() {
buf := bytes.NewBufferString("Hello, world!")
buf.Truncate(3)
fmt.Println(buf.String()) // Output: Hel
buf.Reset()
fmt.Println(buf.String()) // Output:
}
容量控制
Buffer 的容量是自动扩容的,可以通过 Available
(方法签名:func (b *bytes.Buffer) Available() int
)来获取当前分配的剩余容量,使用 AvailableBuffer
(方法签名:func (b *bytes.Buffer) AvailableBuffer() []byte
)来获得可用的 Buffer,增加其内容后,再写入原始的 Buffer。
如果需要手动扩容也可以调用 Grow
(方法签名:func (b *bytes.Buffer) Grow(n int)
)方法来指定要增加的容量。通过 Len
方法可以获取 Buffer 中内容长度,Cap
方法来获取 Buffer 大小。
go
package main
import (
"bytes"
"fmt"
)
func main() {
var buf bytes.Buffer
fmt.Println(buf.Available(), buf.Len(), buf.Cap()) // 0 0 0
buf.Write([]byte("Hello, world!"))
fmt.Println(buf.Available(), buf.Len(), buf.Cap()) // 51 13 64
buf.Grow(64)
fmt.Println(buf.Available(), buf.Len(), buf.Cap()) // 115 13 128
}