抗遗忘: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
}
相关推荐
梦想很大很大5 小时前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰10 小时前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
却尘13 小时前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤14 小时前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
mtngt111 天前
AI DDD重构实践
go
Grassto3 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto4 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室5 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题5 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉7 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想