• Golang bytes.buffer详解


    原文:https://www.jianshu.com/p/e53083132a25

    Buffer 介绍
    Buffer 是 bytes 包中的一个 type Buffer struct{…}
    A buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use.

    (是一个变长的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一个 空的 buffer,但是可以使用)
    Buffer 就像一个集装箱容器,可以存东西,取东西(存取数据)

    创建缓冲器

    func main() {
        buf1 := bytes.NewBufferString("hello")
        buf2 := bytes.NewBuffer([]byte("hello"))
        buf3 := bytes.NewBuffer([]byte{'h','e','l','l','o'})
        fmt.Printf("%v,%v,%v
    ",buf1,buf2,buf3)
        fmt.Printf("%v,%v,%v
    ",buf1.Bytes(),buf2.Bytes(),buf3.Bytes())
    
        buf4 := bytes.NewBufferString("")
        buf5 := bytes.NewBuffer([]byte{})
        fmt.Println(buf4.Bytes(),buf5.Bytes())
    }

    输出

    hello,hello,hello
    [104 101 108 108 111],[104 101 108 108 111],[104 101 108 108 111]
    [] []

    写入到缓冲器
    buffer在new的时候是空的,也是可以直接Write的

    Write

    func (b *Buffer) Write(p []byte) (n int,err error)
    func main() {
    s := []byte(" world")
    buf := bytes.NewBufferString("hello")
    fmt.Printf("%v,%v
    ",buf.String(),buf.Bytes())
    buf.Write(s)
    fmt.Printf("%v,%v
    ",buf.String(),buf.Bytes())
    }

    结果

    hello,[104 101 108 108 111]
    hello world,[104 101 108 108 111 32 119 111 114 108 100]

    WriteString

    func (b *Buffer) WriteString(s string)(n int,err error)
    func main() {
        s := " world"
        buf := bytes.NewBufferString("hello")
        fmt.Printf("%v,%v
    ",buf.String(),buf.Bytes())
        buf.WriteString(s)
        fmt.Printf("%v,%v
    ",buf.String(),buf.Bytes())
    }

    结果

    hello,[104 101 108 108 111]
    hello world,[104 101 108 108 111 32 119 111 114 108 100]
    缓冲区原理介绍
    go字节缓冲区底层以字节切片做存储,切片存在长度len与容量cap, 缓冲区写从长度len的位置开始写,当len>cap时,会自动扩容。缓冲区读会从内置标记off位置开始读(off始终记录读的起始位置),当off==len时,表明缓冲区已全部读完
    并重置缓冲区(len=off=0),此外当将要内容长度+已写的长度(即len) <= cap/2时,缓冲区前移覆盖掉已读的内容(off=0,len-=off),从避免缓冲区不断扩容
    func main() {
        byteSlice := make([]byte, 20) 
        byteSlice[0] = 1                                  // 将缓冲区第一个字节置1
        byteBuffer := bytes.NewBuffer(byteSlice)          // 创建20字节缓冲区 len = 20 off = 0
        c, _ := byteBuffer.ReadByte()                     // off+=1
        fmt.Printf("len:%d, c=%d
    ", byteBuffer.Len(), c) // len = 20 off =1   打印c=1
        byteBuffer.Reset()                                // len = 0 off = 0
        fmt.Printf("len:%d
    ", byteBuffer.Len())          // 打印len=0
        byteBuffer.Write([]byte("hello byte buffer"))     // 写缓冲区  len+=17
        fmt.Printf("len:%d
    ", byteBuffer.Len())          // 打印len=17
        byteBuffer.Next(4)                                // 跳过4个字节 off+=4
        c, _ = byteBuffer.ReadByte()                      // 读第5个字节 off+=1
        fmt.Printf("第5个字节:%d
    ", c)                    // 打印:111(对应字母o)    len=17 off=5
        byteBuffer.Truncate(3)                            // 将未字节数置为3        len=off+3=8   off=5
        fmt.Printf("len:%d
    ", byteBuffer.Len())          // 打印len=3为未读字节数  上面len=8是底层切片长度
        byteBuffer.WriteByte(96)                          // len+=1=9 将y改成A
        byteBuffer.Next(3)                                // len=9 off+=3=8
        c, _ = byteBuffer.ReadByte()                      // off+=1=9    c=96
        fmt.Printf("第9个字节:%d
    ", c)                    // 打印:96
    }
     demo1
    package main
    
    import "bytes"
    import "log"
    
    func main(){
        buf := &bytes.Buffer{}
        buf.WriteString("abcdefg")
    
        str, _ := buf.ReadString('?')
        log.Println("str = ", str)
        log.Println("buff = ", buf.String())
    }

    输出:

    [root@localhost]# go run buffer.go 
    2020/06/05 19:12:42 str =  abcdefg
    2020/06/05 19:12:42 buff =  

     demo2

    // MyBuffer2 project main.go
    package main
    
    import (
        "bytes"
        "log"
        "os"
    )
    
    func main() {
        log.SetFlags(log.Lshortfile)
        buff := bytes.NewBufferString("123456789")
        log.Println("buff = ", buff.String())
    
        s := make([]byte, 4)
        n, _ := buff.Read(s)
        log.Println("buff = ", buff.String())
        log.Println("s = ", string(s))
        log.Println("n = ", n)
    
        n, _ = buff.Read(s)
        log.Println("buff = ", buff.String())
        log.Println("s = ", string(s))
        log.Println("n = ", n)
    
        n, _ = buff.Read(s)
        log.Println("buff = ", buff.String())
        log.Println("s = ", string(s))
        log.Println("n = ", n)
    
        buff.Reset()
        buff.WriteString("abcdefg")
        log.Println("buff = ", buff.String())
    
        b, _ := buff.ReadByte()
        log.Println("b = ", string(b))
        log.Println("buff = ", buff.String())
    
        b, _ = buff.ReadByte()
        log.Println("b = ", string(b))
        log.Println("buff = ", buff.String())
    
        bs, _ := buff.ReadBytes('e')
        log.Println("bs = ", string(bs))
        log.Println("buff = ", buff.String())
    
        buff.Reset()
        buff.WriteString("编译输出GO")
        r, l, _ := buff.ReadRune()
        log.Println("r = ", r, ", l = ", l, ", string(r) = ", string(r))
    
        buff.Reset()
        buff.WriteString("qwer")
        str, _ := buff.ReadString('?')
        log.Println("str = ", str)
        log.Println("buff = ", buff.String())
    
        buff.WriteString("qwer")
        str, _ = buff.ReadString('w')
        log.Println("str = ", str)
        log.Println("buff = ", buff.String())
    
        file, _ := os.Open("doc.go")
        buff.Reset()
        buff.ReadFrom(file)
        log.Println("doc.go = ", buff.String())
    
        buff.Reset()
        buff.WriteString("中国人")
        cbyte := buff.Bytes()
        log.Println("cbyte = ", cbyte)
    }

    输出:

    C:/Go/bin/go.exe build -i [D:/golang/src/MyBuffer2]
    成功: 进程退出代码 0.
    D:/golang/src/MyBuffer2/MyBuffer2.exe  [D:/golang/src/MyBuffer2]
    main.go:13: buff =  123456789
    main.go:17: buff =  56789
    main.go:18: s =  1234
    main.go:19: n =  4
    main.go:22: buff =  9
    main.go:23: s =  5678
    main.go:24: n =  4
    main.go:27: buff =  
    main.go:28: s =  9678
    main.go:29: n =  1
    main.go:33: buff =  abcdefg
    main.go:36: b =  a
    main.go:37: buff =  bcdefg
    main.go:40: b =  b
    main.go:41: buff =  cdefg
    main.go:44: bs =  cde
    main.go:45: buff =  fg
    main.go:50: r =  32534 , l =  3 , string(r) =  编
    main.go:55: str =  qwer
    main.go:56: buff =  
    main.go:60: str =  qw
    main.go:61: buff =  er
    main.go:66: doc.go =  // MyBuffer2 project doc.go
    
    /*
    MyBuffer2 document
    */
    package main
    
    main.go:71: cbyte =  [228 184 173 229 155 189 228 186 186]
    成功: 进程退出代码 0.
  • 相关阅读:
    P3704 [SDOI2017]数字表格
    CF 700 E. Cool Slogans
    杜教筛学习笔记
    [BOI2004]Sequence 数字序列(左偏树)
    [WC2007]剪刀石头布(最大流)
    [NOI2009]变换序列(二分图匹配)
    文理分科(最小割)
    上帝与集合的正确用法(欧拉定理)
    [HAOI2008]圆上的整点(数论)
    主席树学习笔记
  • 原文地址:https://www.cnblogs.com/wangjq19920210/p/13051447.html
Copyright © 2020-2023  润新知