Golang bufio.Reader ReadLine学习

之前学习go的时候被这个ReadLine坑了一段时间,以为加个for循环就会一行一行的读下去。当时好像调试了半天之类的,总之今天来带你们看看他怎么实现的吧。


首先我们构造一个Reader方便我们调试与分析:

sr := strings.NewReader("123\n456");
reader := bufio.NewReader(sr);
line, _, err := reader.ReadLine();
if err != nil {
    panic(err)
}
fmt.Println(string(line))

输出:123
这个时候你也大致明白这个函数的内部原理了吧。他会读取\n之前的数据也就是”123”返回给我们。


ReadLine的源码分析:

以下完全是个人理解如果有错误那就再下面评论吧。

line, err = b.ReadSlice('\n')

首先从第一行代码开始同是最重要的一行代码,这行代码是以\n为结束符读取数据。

if err == ErrBufferFull {
    // Handle the case where "\r\n" straddles the buffer.
    if len(line) > 0 && line[len(line)-1] == '\r' {
        // Put the '\r' back on buf and drop it from line.
        // Let the next call to ReadLine check for "\r\n".
        if b.r == 0 {
            // should be unreachable
            panic("bufio: tried to rewind past start of buffer")
        }
        b.r--
        line = line[:len(line)-1]
    }
    return line, true, nil
}

这个ErrBufferFull 暂时不知道从哪里返回的,等以后发现了会修改。

if len(line) == 0 {
    if err != nil {
        line = nil
    }
    return
}

这几行代码主要是做一个为空判断,很容易理解。

if line[len(line)-1] == '\n' {
    drop := 1
    if len(line) > 1 && line[len(line)-2] == '\r' {
        drop = 2
    }
    line = line[:len(line)-drop]
}

这几行代码是处理line最后两位数据有\n \r

  • 数据的最后一位为'\n'
  • 如果line长度大于1并且倒数第二位为 '\r'截取长度+1
  • 截取数组

你可能感兴趣的:(Golang)