包:bufio

夜里睡不着,再写一篇
bufio主要包含的是带缓冲的IO操作,表面上看不难,但是源码研究下还是挺有意思的,来看看大佬是怎么写代码的,首先从Writer开始说

Writer

带缓冲的Writer图解

缓冲就像一个装水的瓶子,如果瓶子不满就可以一直往里面倒水。过程很生活化,可以看到这个倒水过程需要解决下面几个问题:
一、瓶子的容量是固定的,当前水位是不确定的,要随时准确记录
二、准备倒的水(C1)要和剩余的缓冲(C2)进行比较,根据比较结果进行后续操作

主要的原理就是上述两条,下面画个图直观看下

其中buf是一个[]byte,容量固定。n表示当前已缓存的容量,那么剩余容量 = len(buf) - n

方法:Write(p []byte)

func (b *Writer) Write(p []byte) (nn int, err error) {
    for len(p) > b.Available() && b.err == nil {
        var n int
        if b.Buffered() == 0 {
            n, b.err = b.wr.Write(p)
        } else {
            n = copy(b.buf[b.n:], p)
            b.n += n
            b.Flush()
        }
        nn += n
        p = p[n:]
    }
    if b.err != nil {
        return nn, b.err
    }
    n := copy(b.buf[b.n:], p)
    b.n += n
    nn += n
    return nn, nil
}

解释:
1. 首先判断准备写入的字节数,如果大于剩余容量
一、如果容器为空,则直接调用wr循环写入,这种情况下,缓冲区基本没有参与
二、如果容器剩余容量不为0,则先倒入然后执行Flush,剩余的继续比较。

2.如果不大于剩余容量,则写入容器缓存起来

具体的算法就不再每步说明,看代码一目了然

原文地址:https://www.cnblogs.com/tinaluo/p/14553144.html