bytes.Buffer

simplewater發表於2019-10-20

Buffer是一個實現了讀寫方法的可變大小的位元組緩衝。本型別的零值是一個空的可用於讀寫的緩衝。

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

這東西看來看去就是一個緩衝區,好像沒什麼卵用,就是一個用來暫時存放資料的地方。
裡面就兩種方法,一種是Read一種是Write。

Read方法,主要是從buff中讀取資料

讀的時候buff裡面的指標跟著增加偏移,也就是說,讀過的資料一般情況下是沒法再讀一次的,
但這包裡有 UnreadRune、UnreadByte這種方法,可以把off往回退一些值,但是作用有限,UnreadRune只能回退一個rune佔用的位元組並且必須要之前呼叫過 ReadRune方法才行,UnreadByte只能回退一個位元組,還不能重複回退,這有個毛用啊,Read方法讀出來的資料根本沒法把off回退回去。

// 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.
//儘量把p填滿,返回填充的位元組數。如果本身這個buff是nil或者讀取len(p)個位元組成功,那err就會返回nil。沒填滿err//就返回EOF。
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
}

Write方法主要往buff裡寫入資料

write往裡面寫資料的時候會自動擴大buff的容量,
在gorw方法裡面:capacity如果擴大到超過
2*c + n > maxInt 會觸發panic (c為buff的capacity)
const maxInt = int(^uint(0) >> 1) //本機的int是64位,所以這裡是2的63次方,前面一位是符號位,單位是位元組,分配得快要到64位系統最大記憶體容量了,這遊戲能玩?,一般不會這樣的,絕對不會,我說的。

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

包裡面其他方法都是以Read和Write方法的延伸,要用的時候再去看就行。

相關文章