zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    SharePoint与RMS集成中关于权限的一个技术点
    SharePoint Alert
    SharePoint Explorer View
    在查看network traffic的时候, TCP Chimney offload的影响
    SharePoint Profile Import
    为SharePoint添加Event Receiver
    通过Telnet来发送邮件
    如何查看扩展出来的web application?
    Windows Host 文件
    Wscript.Shell 对象详细介绍
  • 原文地址:https://www.cnblogs.com/ricklz/p/13188152.html
Copyright © 2011-2022 走看看