// ReadAll reads from r until an error or EOF and returns the data it read. // A successful call returns err == nil, not err == EOF. Because ReadAll is // defined to read from src until EOF, it does not treat an EOF from Read // as an error to be reported. // ReadAll从r读取数据直到EOF或遇到error,返回读取的数据和遇到的错误。 // 成功的调用返回的err为nil而非EOF。 // 因为本函数定义为读取r直到EOF,它不会将读取返回的EOF视为应报告的错误。 funcReadAll(r io.Reader)([]byte, error) { return readAll(r, bytes.MinRead) }
// readAll reads from r until an error or EOF and returns the data it read // from the internal buffer allocated with a specified capacity. // readAll从r读取到一个错误或EOF,并返回从指定容量分配的内部缓冲区中读取的数据。 funcreadAll(r io.Reader, capacity int64)(b []byte, err error) { // 新建了一个buffer var buf bytes.Buffer // If the buffer overflows, we will get bytes.ErrTooLarge. // Return that as an error. Any other panic remains. // 如果buffer溢出了,会得到一个bytes.ErrTooLarge的错误 // 如果得到的是bytes.ErrTooLarge错误,将其返回,其他panic错误,仍然panic deferfunc() { e := recover() if e == nil { return } if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge { err = panicErr } else { panic(e) } }() // 判断capacity的值是否超过了int类型的上限 ifint64(int(capacity)) == capacity { // 向buffer当中增加capacity的容量 buf.Grow(int(capacity)) } // 使用buffer ReadFrom 方法读取所有的io.Reader数据 _, err = buf.ReadFrom(r) return buf.Bytes(), err }
// 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是一个实现了读写方法的可变大小的字节缓冲。 // 本类型的零值是一个空的可用于读写的缓冲。 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. // FIXME: lastRead can fit in a single byte
// memory to hold first slice; helps small buffers avoid allocation. // FIXME: it would be advisable to align Buffer to cachelines to avoid false // sharing. bootstrap [64]byte }
4. buffer.Grow
这个方法主要用来增加缓冲区的内存,实际还是调用了非导出的grow方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 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. // 必要时会增加缓冲的容量,以保证n字节的剩余空间。 // 调用Grow(n)后至少可以向缓冲中写入n字节数据而无需申请内存。 // 如果n小于零或者不能增加容量都会panic ErrTooLarge 错误。 func(b *Buffer)Grow(n int) { if n < 0 { panic("bytes.Buffer.Grow: negative count") } m := b.grow(n) b.buf = b.buf[0:m] }
// 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. // ReadFrom从r中读取数据直到结束并将读取的数据写入缓冲中,如必要会增加缓冲容量。 // 返回值n为从r读取并写入b的字节数;会返回读取时遇到的除了io.EOF之外的错误。 // 如果缓冲太大,ReadFrom会采用错误值ErrTooLarge引发panic。 func(b *Buffer)ReadFrom(r io.Reader)(n int64, err error) { // const opInvalid = 0 // Non-read operation. 表示之前没有读操作 b.lastRead = opInvalid // If buffer is empty, reset to recover space. // 如果缓冲区为空,重置为恢复空间。 if b.off >= len(b.buf) { b.Reset() } // 循环读取io.Reader 的数据 for { // 判断当前剩余空间是否小于MinRead,MinRead = 512 if free := cap(b.buf) - len(b.buf); free < MinRead { // not enough space at end // 空间不足 // 新建一个buf newBuf := b.buf // 判断实际剩余容量是否小于MinRead = 512 if b.off+free < MinRead { // not enough space using beginning of buffer; // double buffer capacity // 实际剩余空间不足,分配双倍的缓冲空间,缓冲的最小值为MinRead所以加上一个MinRead,避免双倍之后仍然比MinRead小 // makeSlice函数用于分配缓冲空间,如果分配失败会panic ErrTooLarge 错误 newBuf = makeSlice(2*cap(b.buf) + MinRead) } // 将原有buf数据复制到新的buf copy(newBuf, b.buf[b.off:]) // len(b.buf)-b.off 就等于buf当前内容的长度 // 例子: a:=make([]byte,20) // b:=a[:10] // len(b) // 10 // cap(b) //20 b.buf = newBuf[:len(b.buf)-b.off] // 将off置0 b.off = 0 } // 从io.Reader当中读取数据,传入buf的剩余空间 // 第一种情况,数据读取完毕,返回读取长度m以及,io.EOF错误 // 第二种情况, 数据未读完,遇到错误 // 第三种情况,数据未读完,缓冲区容量不够,返回读取数据长度m以及nil m, e := r.Read(b.buf[len(b.buf):cap(b.buf)]) // 只获取有数据的buf,无数据的空间转化为cap b.buf = b.buf[0 : len(b.buf)+m] n += int64(m) // 数据读取完毕跳出循环 if e == io.EOF { break } // 遇到错误返回 if e != nil { return n, e } } return n, nil// err is EOF, so return nil explicitly }