快乐的天使 發表於 2020-6-24 16:21:00

go中bytes.Buffer使用小结

<ul>
<li>buffer
<ul>
<li>前言</li>
<li>例子</li>
<li>了解下bytes.buffer
<ul>
<li>如何创建bytes.buffer</li>
<li>bytes.buffer的数据写入
<ul>
<li>写入string</li>
<li>写入[]byte</li>
<li>写入byte</li>
<li>写入rune</li>
<li>从文件写入</li>
</ul>
</li>
<li>数据写出
<ul>
<li>写出数据到io.Writer</li>
<li>Read</li>
<li>ReadByte</li>
<li>ReadRune</li>
<li>ReadBytes</li>
<li>ReadString</li>
<li>Next</li>
</ul>
</li>
</ul>
</li>
<li>参考</li>
</ul>
</li>
</ul>

<h2 id="buffer">buffer</h2>
<h3 id="前言">前言</h3>
<p>最近操作文件,进行优化使用到了<code>buffer</code>。好像也不太了解这个,那么就梳理下,<code>buffer</code>的使用。</p>
<h3 id="例子">例子</h3>
<p>我的场景:使用<code>xml</code>拼接了<code>office2003</code>的文档。写入到<code>buffer</code>,然后处理完了,转存到文件里面。</p>
<pre><code class="language-go">type Buff struct {
        Buffer *bytes.Buffer
        Writer *bufio.Writer
}

// 初始化
func NewBuff() *Buff {
        b := bytes.NewBuffer([]byte{})
        return &amp;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")
}
</code></pre>
<h3 id="了解下bytesbuffer">了解下bytes.buffer</h3>
<p><code>bytes.buffer</code>是一个缓冲<code>byte</code>类型的缓冲器,这个缓冲器里存放着都是<code>byte</code>。</p>
<h4 id="如何创建bytesbuffer">如何创建bytes.buffer</h4>
<p>放几种创建的方式</p>
<pre><code class="language-go">        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)
    // 以上两者等效
</code></pre>
<p>查看源码可知</p>
<pre><code class="language-go">func NewBuffer(buf []byte) *Buffer { return &amp;Buffer{buf: buf} }

func NewBufferString(s string) *Buffer {
        return &amp;Buffer{buf: []byte(s)}
}
</code></pre>
<p><code>NewBufferString</code>也是将参数转成 <code>[]byte()</code>。然后,初始化<code>Buffer</code>。</p>
<h4 id="bytesbuffer的数据写入">bytes.buffer的数据写入</h4>
<h5 id="写入string">写入string</h5>
<pre><code class="language-go">        buf := bytes.NewBuffer([]byte{})
        buf.WriteString("小花猫")
        fmt.Println(buf.String())
</code></pre>
<h5 id="写入byte">写入[]byte</h5>
<pre><code class="language-go">    buf := bytes.NewBuffer([]byte{})
        s := []byte("小黑猫")
        buf.Write(s)
        fmt.Println(buf.String())
</code></pre>
<h5 id="写入byte-1">写入byte</h5>
<pre><code class="language-go">        var b byte = '?'
        buf.WriteByte(b)

        fmt.Println(buf.String())
</code></pre>
<h5 id="写入rune">写入rune</h5>
<pre><code class="language-go">        var r rune = '小'
        buf.WriteRune(r)
        fmt.Println(buf.String())
</code></pre>
<h5 id="从文件写入">从文件写入</h5>
<pre><code class="language-go">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”
</code></pre>
<h4 id="数据写出">数据写出</h4>
<h5 id="写出数据到iowriter">写出数据到io.Writer</h5>
<pre><code class="language-go">        file, _ := os.Open("text.txt")
        buf := bytes.NewBufferString("hello")
        buf.WriteTo(file) // hello写到text.txt文件中了
</code></pre>
<p><code>os.File</code>就是实现<code>io.Writer</code></p>
<h5 id="read">Read</h5>
<pre><code class="language-go">        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还是上次的读出结果
</code></pre>
<h5 id="readbyte">ReadByte</h5>
<pre><code class="language-go">    buf := bytes.NewBufferString("hello")
    fmt.Println(buf.String()) // buf.String()方法是吧buf里的内容转成string,&gt;以便于打印
    b, _ := buf.ReadByte()    // 读取第一个byte,赋值给b
    fmt.Println(buf.String()) // 打印 ello,缓冲器头部第一个h被拿掉
    fmt.Println(string(b))    // 打印 h
</code></pre>
<h5 id="readrune">ReadRune</h5>
<pre><code class="language-go">    buf := bytes.NewBufferString("好hello")
    fmt.Println(buf.String()) // buf.String()方法是吧buf里的内容转成string,&gt;以便于打印
    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
</code></pre>
<h5 id="readbytes">ReadBytes</h5>
<p><code>ReadBytes</code>和<code>ReadByte</code>是有区别的。<code>ReadBytes</code>需要一个分隔符来对<code>buffer</code>进行分割读取。</p>
<pre><code class="language-go">    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
</code></pre>
<h5 id="readstring">ReadString</h5>
<p><code>ReadString</code>和<code>ReadBytes</code>一样,也是需要一个分隔符进行,<code>buffer</code></p>
<pre><code class="language-go">        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
</code></pre>
<h5 id="next">Next</h5>
<p>使用<code>Next</code>可依次读出固定长度的内容</p>
<pre><code class="language-go">        buf := bytes.NewBufferString("hello")
        fmt.Println(buf.String())
        b := buf.Next(2)          // 重头开始,取2个
        fmt.Println(buf.String()) // 变小了
        fmt.Println(string(b))    // 打印he
</code></pre>
<h3 id="参考">参考</h3>
<p>【go语言的bytes.buffer】https://my.oschina.net/u/943306/blog/127981</p><br><br>
来源:https://www.cnblogs.com/ricklz/p/13188152.html
頁: [1]
查看完整版本: go中bytes.Buffer使用小结