分析来源: 以'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():
和 b.fill()
我们可以从这两个函数中看出, 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().
^.^ 个人 看代码感想, 想再次看到时不会忘记, 只是粗略分析, 希望 如果有发现错误的地方,能够指出来,谢谢~