Reader结构如下
type Reader struct {
buf []byte
rd io.Reader // reader provided by the client
r, w int // buf read and write positions
err error
lastByte int
lastRuneSize int
}
包含两个new方法
func NewReaderSize(rd io.Reader, size int)
func NewReader(rd io.Reader)
第二个不带size的使用defaultBufSize,另外size最小为16
Reader.Read如下
func (b *Reader) Read(p []byte) (n int, err error) {
n = len(p)
if n == 0 {
return 0, b.readErr()
}
if b.r == b.w { //读写位置相等 即读取完了
if b.err != nil { //有错误
return 0, b.readErr()
}
if len(p) >= len(b.buf) { //若读取长度大于等于buf
// Large read, empty buffer.
// Read directly into p to avoid copy.
n, b.err = b.rd.Read(p) //直接从io.Reader中读取p长度数据
if n < 0 {
panic(errNegativeRead)
}
if n > 0 {
b.lastByte = int(p[n-1])
b.lastRuneSize = -1
}
return n, b.readErr()
}
// One read.
// Do not use b.fill, which will loop.
b.r = 0
b.w = 0
n, b.err = b.rd.Read(b.buf) //直接从io.Reader中读取buf大小的数据
if n < 0 {
panic(errNegativeRead)
}
if n == 0 {
return 0, b.readErr()
}
b.w += n //写长度+n
}
// copy as much as we can
n = copy(p, b.buf[b.r:b.w]) //从读取长度到目前总长度
b.r += n //设置读取位置
b.lastByte = int(b.buf[b.r-1])
b.lastRuneSize = -1
return n, nil
}
故如下代码
var test = make([]byte, 8)
var testLong = make([]byte, 16)
var rd = strings.NewReader("123456789123456789123456789123456789")
buf := bufio.NewReaderSize(rd, 16)
log.Println(buf.Read(test))
log.Println(buf.Read(testLong))
两次取出的长度都为8,第一次取出8,缓存内剩余8,再次读取,将缓存中内容返回,也为8