抗遗忘:Go bytes Buffer 笔记

创建缓冲区

方法签名:

  • 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)

ReadBytesReadString 功能一样,区别在于返回的一个是字节切片,一个是字符串。

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
}

ReadFromio.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)来取消最近一次成功读取的最后一个 byterune 内容。

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
}
相关推荐
梁梁梁梁较瘦1 天前
边界检查消除(BCE,Bound Check Elimination)
go
梁梁梁梁较瘦1 天前
指针
go
梁梁梁梁较瘦1 天前
内存申请
go
半枫荷1 天前
七、Go语法基础(数组和切片)
go
梁梁梁梁较瘦2 天前
Go工具链
go
半枫荷2 天前
六、Go语法基础(条件控制和循环控制)
go
半枫荷3 天前
五、Go语法基础(输入和输出)
go
小王在努力看博客3 天前
CMS配合闲时同步队列,这……
go
Anthony_49264 天前
逻辑清晰地梳理Golang Context
后端·go
Dobby_055 天前
【Go】C++ 转 Go 第(二)天:变量、常量、函数与init函数
vscode·golang·go