Reader分析


数据结构

type Reader struct {
    rd   io.Reader     // 被读取的io缓存,可以是网络的或文件的
    buf  []byte        // 缓冲区,用于给rd当缓存使用
    r, w int           // 读写游标,用来管理buf字段的
    err  error         // 存储当前Reader的异常值
}

常量分析

const defaultBufSize = 4096   // 针对Reader中的buf字段,默认缓冲区大小(byte)
const minReadBufferSize = 16  // 在初始化Reader结构的时候,能够设置的最小的缓冲区大小
const maxConsecutiveEmptyReads = 100  // 从rd中读取数据无数据(fill操作)返回时(n==0)时,最多的读取次数

函数分析
func (b *Reader) fill();

1、缓存对齐,如果读游标不在缓存的起始位置,则将可读数据对齐到起始位置copy(buf,buf[r:w])
2、经过对齐后,如果w的游标超出了缓冲区的长度,则抛出一次异常
3、尝试maxConsecutiveEmptyReads次从rd中读取数据到buf中,直到出现异常或者成功的读到数据到buf中了返回,如果超出了尝试次数则设置err为io.ErrNoProgress


白色:空闲内存,可写入数据
绿色:已写入内存,可读取数据
灰色:已读取内存,可回收(fill函数在填充数据的同时会处理回收)
0_1558596290334_未命名.png

图中初始时有10个空闲块,R和W都指向下标0处。
向内存中写入了5Byte的数据,这时候R在下标0处,W指向了下标5,这时候的可读数据为W-R=5Byte。
读取了3Byte的数据,这时候R指向下标3,可读数据为W-R = 2,可回收空间为R。
回收已读数据copy(buf,buf[r:w]),将R到W区间的数据平移至buf下标为0的位置。