go ReadString() 函数分析

分析来源: 以'\n' 为一行,读取文件内容。 流程如下:

rd := bufio.NewReader(f)  // f is io.Reader interface.
for{
   line, err := rd.ReadString('\n')
    if err != nil || io.EOF ==err{
       break
   }
}

进入ReadString() :


将在rd中查找, 并将返回的[]byte 转换成 string与err 一并返回。

进入 ReadBytes():

 func (b *Reader) ReadBytes(delim byte) (line []byte, err error) {
     var frag []byte
     var full [][]byte
 
     for {
        var e error
        frag, e = b.ReadSlice(delim)
         if e == nil { // got final fragment
           break
        }
        if e != ErrBufferFull { // unexpected error
           err = e
            break
        }

         // Make a copy of the buffer.
        buf := make([]byte, len(frag))
        copy(buf, frag)
        full = append(full, buf)
     } 
     // Allocate new buffer to hold the full pieces and the fragment.
     n := 0
     for i := range full {
         n += len(full[i])
     }
     n += len(frag)
     // Copy full pieces and fragment in.
    buf := make([]byte, n)
    n = 0
    for i := range full {
         n += copy(buf[n:], full[i])
     }
    copy(buf[n:], frag)
 }

定义 frag []byte 数组和 full [][] byte 二维数组
现在来看 for 循环中的内容: 只有当 err 为 ErrBufferFull 时, for才会再次循环, 并且 将此时的frag 加入full , 为什么要写成这样子呢?
来看下ReadSlice():
go ReadString() 函数分析_第1张图片
和 b.fill()
go ReadString() 函数分析_第2张图片
我们可以从这两个函数中看出, ReadSlice () 会将 Reader 结构中, r , w 所组成的数组中查找是否含有给定字符, 如果有进行相应的设置,如果没有找到, 而且 数组只是Reader 里buff 里的部分的话, ReadSlice()将会 从Reader io.Reader 所指位置 再次读取字符填满buff , 进而重新查找,看是否有, 这是当 所检查内容小于或等于buff.
当 所检查内容大于buff 时,ReadSlice () 每次填满buff 并且未检测到特定字符'\n' , ReadSlice () 返回ErrBufferfull (检查最大字符数还是没有找到), 继而 ReadBytes() for 中 : full 存储着buff数据, 再接着找,直到找到,或者 err 为 io.EOF , 结束。

note :
1. fill () 读取字符进入buff 直到填满( EOF 错误除外)
2. ReadSlice() 如果没有检测到'\n', 会根据 检测范围是否 全部而判断, 如果 是 全部buff的字符数, 则 会退 出, 如果不是, 会再读取数据直至满buff 重新检测, 再没有的话, 则会退出
3.ReadBytes() 会存储 满buff检测而是 ErrBufferFull 错误, 将再次调用 ReadSlice () 读入buff量的数据, 进行测试,最终 会err == nil 或者是 ,比如文件被读完, err = io.EOF 错误, 返回给ReadString().

^.^ 个人 看代码感想, 想再次看到时不会忘记, 只是粗略分析, 希望 如果有发现错误的地方,能够指出来,谢谢~

转载于:https://my.oschina.net/longtian/blog/818765

你可能感兴趣的:(go ReadString() 函数分析)