go中bytes.Buffer使用小結


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

ReadBytesReadByte是有區別的。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

ReadStringReadBytes一樣,也是需要一個分隔符進行,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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM