SoFunction
Updated on 2025-03-05

How to use go native library

1 Definition

Provides an extensible byte buffer, which is essentially an encapsulation of slices; the structure contains a small 64-byte slice to avoid small memory allocation:

// 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)]--->Instruction read pointer bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
 lastRead  readOp   // last read operation, so that Unread* can work correctly.
}

2 Initialization method

1) var buf -> define an empty byte buffer

2) func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} } --> Initialize the byte slice into a buffer

3) func NewBufferString(s string) *Buffer {return &Buffer{buf: []byte(s)}} -->Initialize the string into a buffer

3 The main API functions provided

1) Write byte stream data to the buffer

// 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) {
  = opInvalid
 m := (len(p))
 return copy([m:], p), nil
}

2) Write string to buffer

// 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) {
  = opInvalid
 //Return to the written index m := (len(s))
 return copy([m:], s), nil
}

3) Read data from the buffer

// 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  (unless len(p) is zero);
// otherwise it is nil.
func (b *Buffer) Read(p []byte) (n int, err error) {
  = opInvalid
 if  >= len() {
  // Buffer is empty, reset to recover space.
  (0)
  if len(p) == 0 {
   return
  }
  return 0, 
 }
 n = copy(p, [:])
  += n
 if n > 0 {
   = opRead
 }
 return
}

4) Read the string from the buffer until the delim position

// 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 ).
// 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 := (delim)
 return string(slice), err
}

5) Return the unread byte data

// Bytes returns a slice of length () 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 [:] }

6) Return unread byte data as a string

// String returns the contents of the unread portion of the buffer
// as a string. If the Buffer is a nil pointer, it returns "<nil>".
func (b *Buffer) String() string {
 if b == nil {
  // Special case, useful in debugging.
  return "<nil>"
 }
 return string([:])
}

7) Return the current capacity of the buffer

// 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() }

8) Return the byte data size that is not read

// Len returns the number of bytes of the unread portion of the buffer;
// () == len(()).
func (b *Buffer) Len() int { return len() -  }

4 Automatic expansion mechanism

When writing data to the buffer, first check whether the current capacity meets the requirements. If it is not met, it is handled in three cases:

1) The current built-in buffer slice buf is empty and the amount of data written is less than the size of bootstrap (64 bytes), then bootstrap is used as a buf

2) The current unread data length + the newly written data length is less than or equal to 1/2 of the buffer capacity, then move the data (put the unread data to the read data position)

3) If the above conditions are not met, you can only reassign the slices. The capacity is set to 2*cap() + n, that is, twice the original buffer capacity + the write data size

// 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 := ()
 // If buffer is empty, reset to recover space.
 if m == 0 &amp;&amp;  != 0 {
  (0)
 }
 //If the required capacity is greater than the current capacity---> if len()+n &gt; cap() {
  var buf []byte
  //The existing preparation 64byte can meet  if  == nil &amp;&amp; n &lt;= len() {
   buf = [0:]
   //The actual required is less than the slice capacity  } else if m+n &lt;= cap()/2 {
   // We can slide things down instead of allocating a new
   // slice. We only need m+n &lt;= cap() to slide, but
   // we instead let capacity get twice as large so we
   // don't spend all our time copying.
   copy([:], [:])
   buf = [:m]
  } else {
   // not enough space anywhere
   //Not enough, then allocate 2 times plus n capacity   buf = makeSlice(2*cap() + n)
   copy(buf, [:])
  }
   = buf
   = 0
 }
  = [0 : +m+n]
 return  + m
}

5 limitations

Provides a preliminary encapsulation of slices, but does not do much; it cannot be manipulated for read data.

Supplement: Golang Usage Excerpt

1. Introduction

It is a buffer in the Golang standard library, with read and write methods and variable size byte storage functions. The zero value of the buffer is an empty buffer to be used.

Definition is as follows:

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.
}

Note the key points:

(1) After reading the data, the data that was successfully read remains in the original buffer, but it cannot be used because the visible data in the buffer starts from the offset off, that is, buf[off: len(buf)].

2. Common methods

(1) Declare a Buffer

var b            //Directly define a Buffer variable without initialization, you can use it directlyb := new()       //Return Buffer variable using Newb := (s []byte)     //Slice from a []byte, construct a Bufferb := (s string) //Construct a Buffer from a string variable

(2) Write data into the Buffer

(d []byte) (n int, err error)      //Write slice d to the end of the Buffer(s string) (n int, err error)   //Write string s to the end of the Buffer(c byte) error        //Write character c to the end of the Buffer(r rune) (n int, err error)      //Put a rune type data at the end of the buffer(r ) (n int64, err error) //Write from the readable object that implements the interface to the end of the Buffer

(3) Read data from the Buffer

//Read n bytes of data and return. If the buffer is less than n bytes, read all(n int) []byte
//Read len(p) bytes into p at one time, and each time reading new content will overwrite the original content in p.  Successfully returns the actual number of bytes read, off offsets backward n, buffer returns error without data(p []byte) (n int, err error)
//Read the first byte and return, off offset n() (byte, error)
//Read the first UTF8 encoded character and return the character and the number of bytes of the character. The first rune of b is removed.  If the buffer is empty, an error is returned. If it is not a UTF8-encoded character, consume one byte and return (U+FFFD,1,nil)() (r rune, size int, err error)
//Read the content before the first delimiter of the buffer and the delimiter and return it. The buffer will clear the read content.  If no delimiter is found, the read content is returned and the error is returned(delimiter byte) (line []byte, err error)
//Read the content before the first delimiter of the buffer and the delimiter and return it as a string. The buffer will clear the read content.  If no delimiter is found, the read content is returned and the error is returned(delimiter byte) (line string, err error)
//Output the contents in the Buffer to the writeable object that implements the interface, successfully return the number of bytes written, and fail to return the error(w ) (n int64, err error)

(4) Other operations

() []byte  //Return byte slice() int    //Return the capacity of the buffer internal byte slice(n int)   //Increase n bytes to the capacity of the buffer internal byte slice() int    //Return the buffer data length, equal to len(())()     //Clear data() string  //String(n int)  //Drop all bytes in the buffer except for the first n unread bytes.  If n is negative or greater than the buffer length, panic is raised() error //Set the bytes successfully read in the last read operation to the state that was not read, that is, the offset that has been read is reduced by 1() error //Will last ReadRune() The read operation returns UTF8 character runeSet to a state that is not read,The offset that is about to be read off minus character rune Number of bytes

3. Use examples

(1) Read all content from the file and append it to the end of the buffer

The content is:

My name is dablelv

Specific implementation:

package main
import (
 "os"
 "fmt"
 "bytes"
)
func main() {
    file, _ := ("./")    
    buf := ("Hello world ")    
    (file)              //Append the content to the end of the buffer    (())
}

Compile and run output:

Hello world My name is dablelv

The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.