buffer
前言
最近操作文件,進行優化使用到了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
bytes.buffer
是一個緩沖byte
類型的緩沖器,這個緩沖器里存放着都是byte
。
如何創建bytes.buffer
放幾種創建的方式
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
。
bytes.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”
數據寫出
寫出數據到io.Writer
file, _ := os.Open("text.txt")
buf := bytes.NewBufferString("hello")
buf.WriteTo(file) // hello寫到text.txt文件中了
os.File
就是實現io.Writer
Read
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
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
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
使用Next
可依次讀出固定長度的內容
buf := bytes.NewBufferString("hello")
fmt.Println(buf.String())
b := buf.Next(2) // 重頭開始,取2個
fmt.Println(buf.String()) // 變小了
fmt.Println(string(b)) // 打印he
參考
【go語言的bytes.buffer】https://my.oschina.net/u/943306/blog/127981