最近操作文件,进行优化使用到了buffer。好像也不太了解这个,那么就梳理下,buffer的使用。
我的场景:使用xml拼接了office2003的文档。写入到buffer,然后处理完了,转存到文件里面。
type Buff struct {
Buffer *bytes.Buffer
Writer *bufio.Writer
}
// 初始化
func NewBuff() *Buff {
b := bytes.NewBuffer([]byte{})
return &Buff{
Buffer: b,
Writer: bufio.NewWriter(b),
}
}
func (b *Buff) WriteString(str string) error {
_, err := b.Writer.WriteString(str)
return err
}
func (b *Buff) SaveAS(name string) error {
file, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
if err != nil {
return err
}
defer file.Close()
if err := b.Writer.Flush(); err != nil {
return nil
}
_, err = b.Buffer.WriteTo(file)
return err
}
func main() {
var b = NewBuff()
b.WriteString("haah")
}
bytes.buffer
是一个缓冲byte类型的缓冲器,这个缓冲器里存放着都是byte
。
放几种创建的方式
buf1 := bytes.NewBufferString("hello")
fmt.Println(buf1)
buf2 := bytes.NewBuffer([]byte("hello"))
fmt.Println(buf2)
buf3 := bytes.NewBuffer([]byte{byte('h'), byte('e'), byte('l'), byte('l'), byte('o')})
fmt.Println(buf3)
// 以上三者等效
buf4 := bytes.NewBufferString("")
fmt.Println(buf4)
buf5 := bytes.NewBuffer([]byte{})
fmt.Println(buf5)
// 以上两者等效
查看源码可知
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
func NewBufferString(s string) *Buffer {
return &Buffer{buf: []byte(s)}
}
NewBufferString
也是将参数转成[]byte()
。然后,初始化Buffer
。
写入string
buf := bytes.NewBuffer([]byte{})
buf.WriteString("小花猫")
fmt.Println(buf.String())
写入[]byte
buf := bytes.NewBuffer([]byte{})
s := []byte("小黑猫")
buf.Write(s)
fmt.Println(buf.String())
写入byte
var b byte = '?'
buf.WriteByte(b)
fmt.Println(buf.String())
写入rune
var r rune = '小'
buf.WriteRune(r)
fmt.Println(buf.String())
从文件写入
file, err := os.Open("./buffer/test.txt") //test.txt的内容是“world”
if err != nil {
fmt.Println(err)
}
defer file.Close()
fmt.Println(file.Sync())
buf := bytes.NewBufferString("hello ")
buf.ReadFrom(file) //将text.txt内容追加到缓冲器的尾部
fmt.Println(buf.String()) //打印“hello world”
file, _ := os.Open("text.txt")
buf := bytes.NewBufferString("hello")
buf.WriteTo(file) // hello写到text.txt文件中了
os.File就是实现io.Writer
bufRead := bytes.NewBufferString("hello")
fmt.Println(bufRead.String())
var sRead = make([]byte, 3) // 定义读出的[]byte为3,表示一次可读出3个byte
bufRead.Read(sRead) // 读出
fmt.Println(bufRead.String()) // 打印结果为lo,因为前三个被读出了
fmt.Println(string(sRead)) // 打印结果为hel,读取的是hello的前三个字母
bufRead.Read(sRead) // 接着读,但是bufRead之剩下lo,所以只有lo被读出了
fmt.Println(bufRead.String()) // 打印结果为空
fmt.Println(string(sRead)) // 打印结果lol,前两位的lo表示的本次的读出,因为bufRead只有两位,后面的l还是上次的读出结果
ReadByte
buf := bytes.NewBufferString("hello")
fmt.Println(buf.String()) // buf.String()方法是吧buf里的内容转成string,>以便于打印
b, _ := buf.ReadByte() // 读取第一个byte,赋值给b
fmt.Println(buf.String()) // 打印 ello,缓冲器头部第一个h被拿掉
fmt.Println(string(b)) // 打印 h
ReadRune
buf := bytes.NewBufferString("好hello")
fmt.Println(buf.String()) // buf.String()方法是吧buf里的内容转成string,>以便于打印
b, n, _ := buf.ReadRune() // 读取第一个rune,赋值给b
fmt.Println(buf.String()) // 打印 hello
fmt.Println(string(b)) // 打印中文字: 好,缓冲器头部第一个“好”被拿掉
fmt.Println(n) // 打印3,“好”作为utf8储存占3个byte
b, n, _ = buf.ReadRune() // 再读取第一个rune,赋值给b
fmt.Println(buf.String()) // 打印 ello
fmt.Println(string(b)) // 打印h,缓冲器头部第一个h被拿掉
fmt.Println(n) // 打印 1,“h”作为utf8储存占1个byte
ReadBytes和ReadByte是有区别的。ReadBytes需要一个分隔符来对buffer进行分割读取。
var d byte = 'e' //分隔符为e
buf := bytes.NewBufferString("hello")
fmt.Println(buf.String()) // buf.String()方法是吧buf里的内容转成string,以便于打印
b, _ := buf.ReadBytes(d) // 读到分隔符,并返回给b
fmt.Println(buf.String()) // 打印 llo,缓冲器被取走一些数据
fmt.Println(string(b)) // 打印 he,找到e了,将缓冲器从头开始,到e的内容都返回给b
ReadString和ReadBytes一样,也是需要一个分隔符进行,buffer
var d byte = 'e' //分隔符为e
buf := bytes.NewBufferString("hello")
fmt.Println(buf.String()) // buf.String()方法是吧buf里的内容转成string,以便于打印
b, _ := buf.ReadString(d) // 读到分隔符,并返回给b
fmt.Println(buf.String()) // 打印 llo,缓冲器被取走一些数据
fmt.Println(b) // 打印 he,找到e了,将缓冲器从头开始,到e的内容都返回给b
使用Next可依次读出固定长度的内容
buf := bytes.NewBufferString("hello")
fmt.Println(buf.String())
b := buf.Next(2) // 重头开始,取2个
fmt.Println(buf.String()) // 变小了
fmt.Println(string(b)) // 打印he