• GoLang之bytes.Builder底层


    GoLang之bytes.Builder底层

    1.1bytes.Builder结构体

    1.1.1bytes.Builder结构体
    // 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.
    type Buffer struct {
    	buf      []byte // contents are the bytes buf[off : len(buf)]
    	off      int    // read at &buf[off], write at &buf[len(buf)]
    	lastRead readOp // last read operation, so that Unread* can work correctly.
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1.1.2Bytes方法
    // Bytes returns a slice of length b.Len() holding the unread portion of the buffer.
    // The slice is valid for use only until the next buffer modification (that is,
    // only until the next call to a method like Read, Write, Reset, or Truncate).
    // The slice aliases the buffer content at least until the next buffer modification,
    // so immediate changes to the slice will affect the result of future reads.
    func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1.1.3String方法
    // String returns the contents of the unread portion of the buffer
    // as a string. If the Buffer is a nil pointer, it returns "".
    //
    // To build strings more efficiently, see the strings.Builder type.
    func (b *Buffer) String() string {
    	if b == nil {
    		// Special case, useful in debugging.
    		return ""
    	}
    	return string(b.buf[b.off:])
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1.1.4empty方法
    // empty reports whether the unread portion of the buffer is empty.
    func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
    
    • 1
    • 2
    1.1.5Len方法
    // Len returns the number of bytes of the unread portion of the buffer;
    // b.Len() == len(b.Bytes()).
    func (b *Buffer) Len() int { return len(b.buf) - b.off }
    
    • 1
    • 2
    • 3
    1.1.6Cap方法
    // Cap returns the capacity of the buffer's underlying byte slice, that is, the
    // total space allocated for the buffer's data.
    func (b *Buffer) Cap() int { return cap(b.buf) }
    
    • 1
    • 2
    • 3
    1.1.7Truncate方法
    // Truncate discards all but the first n unread bytes from the buffer
    // but continues to use the same allocated storage.
    // It panics if n is negative or greater than the length of the buffer.
    func (b *Buffer) Truncate(n int) {
    	if n == 0 {
    		b.Reset()
    		return
    	}
    	b.lastRead = opInvalid
    	if n < 0 || n > b.Len() {
    		panic("bytes.Buffer: truncation out of range")
    	}
    	b.buf = b.buf[:b.off+n]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1.1.8Reset方法
    // Reset resets the buffer to be empty,
    // but it retains the underlying storage for use by future writes.
    // Reset is the same as Truncate(0).
    func (b *Buffer) Reset() {
    	b.buf = b.buf[:0]
    	b.off = 0
    	b.lastRead = opInvalid
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.1.9Grow方法
    // Grow grows the buffer's capacity, if necessary, to guarantee space for
    // another n bytes. After Grow(n), at least n bytes can be written to the
    // buffer without another allocation.
    // If n is negative, Grow will panic.
    // If the buffer can't grow it will panic with ErrTooLarge.
    func (b *Buffer) Grow(n int) {
    	if n < 0 {
    		panic("bytes.Buffer.Grow: negative count")
    	}
    	m := b.grow(n)
    	b.buf = b.buf[:m]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1.1.10Write方法
    // Write appends the contents of p to the buffer, growing the buffer as
    // needed. The return value n is the length of p; err is always nil. If the
    // buffer becomes too large, Write will panic with ErrTooLarge.
    func (b *Buffer) Write(p []byte) (n int, err error) {
    	b.lastRead = opInvalid
    	m, ok := b.tryGrowByReslice(len(p))
    	if !ok {
    		m = b.grow(len(p))
    	}
    	return copy(b.buf[m:], p), nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1.1.11WriteString方法
    // WriteString appends the contents of s to the buffer, growing the buffer as
    // needed. The return value n is the length of s; err is always nil. If the
    // buffer becomes too large, WriteString will panic with ErrTooLarge.
    func (b *Buffer) WriteString(s string) (n int, err error) {
    	b.lastRead = opInvalid
    	m, ok := b.tryGrowByReslice(len(s))
    	if !ok {
    		m = b.grow(len(s))
    	}
    	return copy(b.buf[m:], s), nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1.1.12ReadFrom方法
    // ReadFrom reads data from r until EOF and appends it to the buffer, growing
    // the buffer as needed. The return value n is the number of bytes read. Any
    // error except io.EOF encountered during the read is also returned. If the
    // buffer becomes too large, ReadFrom will panic with ErrTooLarge.
    func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
    	b.lastRead = opInvalid
    	for {
    		i := b.grow(MinRead)
    		b.buf = b.buf[:i]
    		m, e := r.Read(b.buf[i:cap(b.buf)])
    		if m < 0 {
    			panic(errNegativeRead)
    		}
    
    		b.buf = b.buf[:i+m]
    		n += int64(m)
    		if e == io.EOF {
    			return n, nil // e is EOF, so return nil explicitly
    		}
    		if e != nil {
    			return n, e
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1.1.13WriteTo方法
    // WriteTo writes data to w until the buffer is drained or an error occurs.
    // The return value n is the number of bytes written; it always fits into an
    // int, but it is int64 to match the io.WriterTo interface. Any error
    // encountered during the write is also returned.
    func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
    	b.lastRead = opInvalid
    	if nBytes := b.Len(); nBytes > 0 {
    		m, e := w.Write(b.buf[b.off:])
    		if m > nBytes {
    			panic("bytes.Buffer.WriteTo: invalid Write count")
    		}
    		b.off += m
    		n = int64(m)
    		if e != nil {
    			return n, e
    		}
    		// all bytes should have been written, by definition of
    		// Write method in io.Writer
    		if m != nBytes {
    			return n, io.ErrShortWrite
    		}
    	}
    	// Buffer is now empty; reset.
    	b.Reset()
    	return n, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1.1.14WriteByte方法
    // WriteByte appends the byte c to the buffer, growing the buffer as needed.
    // The returned error is always nil, but is included to match bufio.Writer's
    // WriteByte. If the buffer becomes too large, WriteByte will panic with
    // ErrTooLarge.
    func (b *Buffer) WriteByte(c byte) error {
    	b.lastRead = opInvalid
    	m, ok := b.tryGrowByReslice(1)
    	if !ok {
    		m = b.grow(1)
    	}
    	b.buf[m] = c
    	return nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1.1.15WriteRune方法
    // WriteRune appends the UTF-8 encoding of Unicode code point r to the
    // buffer, returning its length and an error, which is always nil but is
    // included to match bufio.Writer's WriteRune. The buffer is grown as needed;
    // if it becomes too large, WriteRune will panic with ErrTooLarge.
    func (b *Buffer) WriteRune(r rune) (n int, err error) {
    	// Compare as uint32 to correctly handle negative runes.
    	if uint32(r) < utf8.RuneSelf {
    		b.WriteByte(byte(r))
    		return 1, nil
    	}
    	b.lastRead = opInvalid
    	m, ok := b.tryGrowByReslice(utf8.UTFMax)
    	if !ok {
    		m = b.grow(utf8.UTFMax)
    	}
    	n = utf8.EncodeRune(b.buf[m:m+utf8.UTFMax], r)
    	b.buf = b.buf[:m+n]
    	return n, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1.1.16Read方法
    // Read reads the next len(p) bytes from the buffer or until the buffer
    // is drained. The return value n is the number of bytes read. If the
    // buffer has no data to return, err is io.EOF (unless len(p) is zero);
    // otherwise it is nil.
    func (b *Buffer) Read(p []byte) (n int, err error) {
    	b.lastRead = opInvalid
    	if b.empty() {
    		// Buffer is empty, reset to recover space.
    		b.Reset()
    		if len(p) == 0 {
    			return 0, nil
    		}
    		return 0, io.EOF
    	}
    	n = copy(p, b.buf[b.off:])
    	b.off += n
    	if n > 0 {
    		b.lastRead = opRead
    	}
    	return n, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    1.1.17Next方法
    // Next returns a slice containing the next n bytes from the buffer,
    // advancing the buffer as if the bytes had been returned by Read.
    // If there are fewer than n bytes in the buffer, Next returns the entire buffer.
    // The slice is only valid until the next call to a read or write method.
    func (b *Buffer) Next(n int) []byte {
    	b.lastRead = opInvalid
    	m := b.Len()
    	if n > m {
    		n = m
    	}
    	data := b.buf[b.off : b.off+n]
    	b.off += n
    	if n > 0 {
    		b.lastRead = opRead
    	}
    	return data
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1.1.18ReadByte方法
    // ReadByte reads and returns the next byte from the buffer.
    // If no byte is available, it returns error io.EOF.
    func (b *Buffer) ReadByte() (byte, error) {
    	if b.empty() {
    		// Buffer is empty, reset to recover space.
    		b.Reset()
    		return 0, io.EOF
    	}
    	c := b.buf[b.off]
    	b.off++
    	b.lastRead = opRead
    	return c, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1.1.19ReadRune方法
    // ReadRune reads and returns the next UTF-8-encoded
    // Unicode code point from the buffer.
    // If no bytes are available, the error returned is io.EOF.
    // If the bytes are an erroneous UTF-8 encoding, it
    // consumes one byte and returns U+FFFD, 1.
    func (b *Buffer) ReadRune() (r rune, size int, err error) {
    	if b.empty() {
    		// Buffer is empty, reset to recover space.
    		b.Reset()
    		return 0, 0, io.EOF
    	}
    	c := b.buf[b.off]
    	if c < utf8.RuneSelf {
    		b.off++
    		b.lastRead = opReadRune1
    		return rune(c), 1, nil
    	}
    	r, n := utf8.DecodeRune(b.buf[b.off:])
    	b.off += n
    	b.lastRead = readOp(n)
    	return r, n, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    1.1.20UnreadRune方法
    // UnreadRune unreads the last rune returned by ReadRune.
    // If the most recent read or write operation on the buffer was
    // not a successful ReadRune, UnreadRune returns an error.  (In this regard
    // it is stricter than UnreadByte, which will unread the last byte
    // from any read operation.)
    func (b *Buffer) UnreadRune() error {
    	if b.lastRead <= opInvalid {
    		return errors.New("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune")
    	}
    	if b.off >= int(b.lastRead) {
    		b.off -= int(b.lastRead)
    	}
    	b.lastRead = opInvalid
    	return nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1.1.21ReadBytes方法
    // ReadBytes reads until the first occurrence of delim in the input,
    // returning a slice containing the data up to and including the delimiter.
    // If ReadBytes encounters an error before finding a delimiter,
    // it returns the data read before the error and the error itself (often io.EOF).
    // ReadBytes returns err != nil if and only if the returned data does not end in
    // delim.
    func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
    	slice, err := b.readSlice(delim)
    	// return a copy of slice. The buffer's backing array may
    	// be overwritten by later calls.
    	line = append(line, slice...)
    	return line, err
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1.1.22readSlice方法
    // readSlice is like ReadBytes but returns a reference to internal buffer data.
    func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
    	i := IndexByte(b.buf[b.off:], delim)
    	end := b.off + i + 1
    	if i < 0 {
    		end = len(b.buf)
    		err = io.EOF
    	}
    	line = b.buf[b.off:end]
    	b.off = end
    	b.lastRead = opRead
    	return line, err
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1.1.23ReadString方法
    // ReadString reads until the first occurrence of delim in the input,
    // returning a string containing the data up to and including the delimiter.
    // If ReadString encounters an error before finding a delimiter,
    // it returns the data read before the error and the error itself (often io.EOF).
    // ReadString returns err != nil if and only if the returned data does not end
    // in delim.
    func (b *Buffer) ReadString(delim byte) (line string, err error) {
    	slice, err := b.readSlice(delim)
    	return string(slice), err
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1.1.24grow方法
    // grow grows the buffer to guarantee space for n more bytes.
    // It returns the index where bytes should be written.
    // If the buffer can't grow it will panic with ErrTooLarge.
    func (b *Buffer) grow(n int) int {
    	m := b.Len()
    	// If buffer is empty, reset to recover space.
    	if m == 0 && b.off != 0 {
    		b.Reset()
    	}
    	// Try to grow by means of a reslice.
    	if i, ok := b.tryGrowByReslice(n); ok {
    		return i
    	}
    	if b.buf == nil && n <= smallBufferSize {
    		b.buf = make([]byte, n, smallBufferSize)
    		return 0
    	}
    	c := cap(b.buf)
    	if n <= c/2-m {
    		// We can slide things down instead of allocating a new
    		// slice. We only need m+n <= c to slide, but
    		// we instead let capacity get twice as large so we
    		// don't spend all our time copying.
    		copy(b.buf, b.buf[b.off:])
    	} else if c > maxInt-c-n {
    		panic(ErrTooLarge)
    	} else {
    		// Not enough space anywhere, we need to allocate.
    		buf := makeSlice(2*c + n)
    		copy(buf, b.buf[b.off:])
    		b.buf = buf
    	}
    	// Restore b.off and len(b.buf).
    	b.off = 0
    	b.buf = b.buf[:m+n]
    	return m
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    1.2 readOp数据类型

    // The readOp constants describe the last action performed on
    // the buffer, so that UnreadRune and UnreadByte can check for
    // invalid usage. opReadRuneX constants are chosen such that
    // converted to int they correspond to the rune size that was read.
    type readOp int8
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3makeSlice函数

    // makeSlice allocates a slice of size n. If the allocation fails, it panics
    // with ErrTooLarge.
    func makeSlice(n int) []byte {
    	// If the make fails, give a known error.
    	defer func() {
    		if recover() != nil {
    			panic(ErrTooLarge)
    		}
    	}()
    	return make([]byte, n)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.4NewBuffer函数

    // NewBuffer creates and initializes a new Buffer using buf as its
    // initial contents. The new Buffer takes ownership of buf, and the
    // caller should not use buf after this call. NewBuffer is intended to
    // prepare a Buffer to read existing data. It can also be used to set
    // the initial size of the internal buffer for writing. To do that,
    // buf should have the desired capacity but a length of zero.
    //
    // In most cases, new(Buffer) (or just declaring a Buffer variable) is
    // sufficient to initialize a Buffer.
    func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.5NewBufferString函数

    // NewBufferString creates and initializes a new Buffer using string s as its
    // initial contents. It is intended to prepare a buffer to read an existing
    // string.
    //
    // In most cases, new(Buffer) (or just declaring a Buffer variable) is
    // sufficient to initialize a Buffer.
    func NewBufferString(s string) *Buffer {
    	return &Buffer{buf: []byte(s)}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.bytes.Builder介绍

    bytes.buffer是一个缓冲byte类型的缓冲器
    bytes.Buffer 是 Golang 标准库中的缓冲区,具有读写方法和可变大小的字节存储功能。缓冲区的零值是一个待使用的空缓冲区。
    注:从 bytes.Buffer 读取数据后,被成功读取的数据仍保留在原缓冲区,只是无法被使用,因为缓冲区的可见数据从偏移 off 开始,即buf[off : len(buf)]。

    3.常用函数

    声明一个Buffer

    var b bytes.Buffer       				//直接定义一个Buffer变量,不用初始化,可以直接使用
    b := new(bytes.Buffer)   				//使用New返回Buffer变量
    b := bytes.NewBuffer(s []byte)   		//从一个[]byte切片,构造一个Buffer
    b := bytes.NewBufferString(s string)	//从一个string变量,构造一个Buffer
    
    • 1
    • 2
    • 3
    • 4

    4.常用方法

    往Buffer中写入数据。

    b.Write(d []byte) (n int, err error)   			//将切片d写入Buffer尾部
    b.WriteString(s string) (n int, err error) 		//将字符串s写入Buffer尾部
    b.WriteByte(c byte) error  						//将字符c写入Buffer尾部
    b.WriteRune(r rune) (n int, err error)    		//将一个rune类型的数据放到缓冲区的尾部
    b.ReadFrom(r io.Reader) (n int64, err error)	//从实现了io.Reader接口的可读取对象写入Buffer尾部
    
    • 1
    • 2
    • 3
    • 4
    • 5

    往Buffer中读取数据。

    //读取 n 个字节数据并返回,如果 buffer 不足 n 字节,则读取全部
    b.Next(n int) []byte
    
    //一次读取 len(p) 个 byte 到 p 中,每次读取新的内容将覆盖p中原来的内容。成功返回实际读取的字节数,off 向后偏移 n,buffer 没有数据返回错误 io.EOF
    b.Read(p []byte) (n int, err error)
    
    //读取第一个byte并返回,off 向后偏移 n
    b.ReadByte() (byte, error)
    
    //读取第一个 UTF8 编码的字符并返回该字符和该字符的字节数,b的第1个rune被拿掉。如果buffer为空,返回错误 io.EOF,如果不是UTF8编码的字符,则消费一个字节,返回 (U+FFFD,1,nil)
    b.ReadRune() (r rune, size int, err error)
    
    //读取缓冲区第一个分隔符前面的内容以及分隔符并返回,缓冲区会清空读取的内容。如果没有发现分隔符,则返回读取的内容并返回错误io.EOF
    b.ReadBytes(delimiter byte) (line []byte, err error)
    
    //读取缓冲区第一个分隔符前面的内容以及分隔符并作为字符串返回,缓冲区会清空读取的内容。如果没有发现分隔符,则返回读取的内容并返回错误 io.EOF
    b.ReadString(delimiter byte) (line string, err error)
    
    //将 Buffer 中的内容输出到实现了 io.Writer 接口的可写入对象中,成功返回写入的字节数,失败返回错误
    b.WriteTo(w io.Writer) (n int64, err error)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    其它操作。

    b.Bytes() []byte		//返回字节切片
    b.Cap() int				//返回 buffer 内部字节切片的容量
    b.Grow(n int)			//为 buffer 内部字节切片的容量增加 n 字节
    b.Len() int				//返回缓冲区数据长度,等于 len(b.Bytes())
    b.Reset() 				//清空数据
    b.String() string		//字符串化
    b.Truncate(n int)		//丢弃缓冲区中除前n个未读字节以外的所有字节。如果 n 为负数或大于缓冲区长度,则引发 panic
    b.UnreadByte() error	//将最后一次读取操作中被成功读取的字节设为未被读取的状态,即将已读取的偏移 off 减 1
    b.UnreadRune() error	//将最后一次 ReadRune() 读取操作返回的 UTF8 字符 rune设为未被读取的状态,即将已读取的偏移 off 减去 字符 rune 的字节数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.使用示例

    从文件 test.txt 中读取全部内容追加到 buffer 尾部。

    test.txt的内容为:
    My name is dablelv

    package main
    
    import (
    	"os"
    	"fmt"
    	"bytes"
    )
    
    func main() {
        file, _ := os.Open("./test.txt")    
        buf := bytes.NewBufferString("Hello world ")    
        buf.ReadFrom(file)              //将text.txt内容追加到缓冲器的尾部    
        fmt.Println(buf.String())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    6.创建缓冲器

    使用bytes.NewBuffer创建:参数是[]byte的话,缓冲器里就是这个slice的内容;如果参数是nil的话,就是创建一个空的缓冲器。

    func main(){
       buf1 := bytes.NewBufferString("hello")
       buf2 := bytes.NewBuffer([]byte("hello"))
       buf3 := bytes.NewBuffer([]byte{'h','e','l','l','o'})
      //以上三者等效,输出:hello
       buf4 := bytes.NewBufferString("")
       buf5 := bytes.NewBuffer([]byte{})
       //以上两者等效,输出:""
       		fmt.Println(buf1.String(),buf2.String(),buf3.String(),buf4,buf5,1)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7.空缓冲器不是nil

    func main() {
    	buf := bytes.NewBufferString("")
    	if buf == nil {
    		fmt.Println("yes")
    	} else {
    		fmt.Println("no")
    	}
    	//输出no
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    8.bytes.Buffer不能与nil对比

    image-20220910091541094

    9.写入到缓冲区

    1.Write方法,将一个byte类型的slice放到缓冲器的尾部

    //func (b *Buffer) Write(p []byte) (n int,err error)
    
    func main(){
       s := []byte(" world")
       buf := bytes.NewBufferString("hello") 
       fmt.Println(buf.String())    //hello
       buf.Write(s)                 //将s这个slice添加到buf的尾部
       fmt.Println(buf.String())   //hello world
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.WriteString方法,把一个字符串放到缓冲器的尾部

    //func (b *Buffer) WriteString(s string)(n int,err error)
    
    func main(){
       s := " world"
       buf := bytes.NewBufferString("hello")
       fmt.Println(buf.String())    //hello
       buf.WriteString(s)           //将string写入到buf的尾部
       fmt.Println(buf.String())    //hello world
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.WriteByte方法,将一个byte类型的数据放到缓冲器的尾部

    //func (b *Buffer) WriteByte(c byte) error
    
    func main(){
       var s byte = '?'
       buf := bytes.NewBufferString("hello") 
       fmt.Println(buf.String()) //把buf的内容转换为string,hello
       buf.WriteByte(s)         //将s写到buf的尾部
       fmt.Println(buf.String()) //hello?
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.WriteRune方法,将一个rune类型的数据放到缓冲器的尾部

    // func (b *Buffer) WriteRune(r Rune) (n int,err error)
    
    func main(){
       var s rune = '好'
       buf := bytes.NewBufferString("hello")
       fmt.Println(buf.String()) //hello
       buf.WriteRune(s)   
       fmt.Println(buf.String()) //hello好
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    10.从缓冲器写出

    WriteTo方法,将一个缓冲器的数据写到w里,w是实现io.Writer的,比如os.File

    func main(){
       file,_ := os.Create("text.txt")
       buf := bytes.NewBufferString("hello world")
       buf.WriteTo(file)
       //或者使用写入,fmt.Fprintf(file,buf.String())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    11.读出缓冲器

    1.Read方法,给Read方法一个容器,读完后p就满了,缓冲器相应的减少。

    // func (b *Buffer) Read(p []byte)(n int,err error)
    
    func main(){
       s1 := []byte("hello")
       buff := bytes.NewBuffer(s1)
       s2 := []byte(" world")
       buff.Write(s2)
       fmt.Println(buff.String()) //hello world
       
       s3 := make([]byte,3)
       buff.Read(s3)     //把buff的内容读入到s3,s3的容量为3,读了3个过来
       fmt.Println(buff.String()) //lo world
       fmt.Println(string(s3))   //hel
       buff.Read(s3) //继续读入3个,原来的被覆盖
       
       fmt.Println(buff.String())     //world
       fmt.Println(string(s3))    //"lo "
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.ReadByte方法,返回缓冲器头部的第一个byte,缓冲器头部第一个byte取出

    //func (b *Buffer) ReadByte() (c byte,err error)
    
    func main(){
       buf := bytes.NewBufferString("hello")
       fmt.Println(buf.String())
       b,_ := buf.ReadByte()   //取出第一个byte,赋值给b
       fmt.Println(buf.String()) //ello
       fmt.Println(string(b))   //h
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.ReadRune方法,返回缓冲器头部的第一个rune

    // func (b *Buffer) ReadRune() (r rune,size int,err error)
    
    func main(){
       buf := bytes.NewBufferString("你好smith")
       fmt.Println(buf.String())
       b,n,_ := buf.ReadRune()  //取出第一个rune
       fmt.Println(buf.String()) //好smith
       fmt.Println(string(b))   //你
       fmt.Println(n)   //3,"你“作为utf8存储占3个byte
    
       b,n,_ = buf.ReadRune()  //再取出一个rune
       fmt.Println(buf.String()) //smith
       fmt.Println(string(b))  //好
       fmt.Println(n)   //3
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4.ReadBytes方法,需要一个byte作为分隔符,读的时候从缓冲器里找出第一个出现的分隔符,缓冲器头部开始到分隔符之间的byte返回。

    //func (b *Buffer) ReadString(delim byte) (line string,err error)
    
    func main(){
       var d byte = 'e'
       buf := bytes.NewBufferString("你好esmieth")
       fmt.Println(buf.String())  //你好esmieth
       b,_ := buf.ReadString(d)   //读取到分隔符,并返回给b
       fmt.Println(buf.String()) //smieth
       fmt.Println(string(b)) //你好e
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.ReadString方法,和ReadBytes方法一样

    //func (b *Buffer) ReadString(delim byte) (line string,err error)
    
    func main(){
       var d byte = 'e'
       buf := bytes.NewBufferString("你好esmieth")
       fmt.Println(buf.String())  //你好esmieth
       b,_ := buf.ReadString(d)   //读取到分隔符,并返回给b
       fmt.Println(buf.String()) //smieth
       fmt.Println(string(b)) //你好e
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    12.读入缓冲区

    ReadFrom方法,从一个实现io.Reader接口的r,把r的内容读到缓冲器里,n返回读的数量

    //func (b *Buffer) ReadFrom(r io.Reader) (n int64,err error)
    
    func main(){
       file, _ := os.Open("text.txt")
       buf := bytes.NewBufferString("bob ")
       buf.ReadFrom(file)
       fmt.Println(buf.String()) //bob hello world
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    13.从缓冲器取出

    Next方法,返回前n个byte(slice),原缓冲器变小

    //func (b *Buffer) Next(n int) []byte
    
    func main(){
       buf := bytes.NewBufferString("hello world")
       fmt.Println(buf.String())
       b := buf.Next(2)  //取前2个
       fmt.Println(buf.String()) //llo world
       fmt.Println(string(b)) //he
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    节能减排 | AIRIOT智慧工厂节能管理解决方案
    Java堆栈区别
    [2023net毕业设计源码]精品基于NET实现的家电维修保养信息系统[包运行成功]
    从Flink的Kafka消费者看算子联合列表状态的使用
    【漏洞复现系列】二、weblogic-cve_2020_2883(RCE/反序列化)
    【Redis】Hash哈希类型
    R语言绘制散点密度图ggdentity
    java基于微信小程序的新冠疫苗接种预约系统 uinapp
    PHP8新特性
    2023软件测试的4个技术等级,你在哪个级别?
  • 原文地址:https://blog.csdn.net/qq_53267860/article/details/126794023