43 | bufio包中的数据类型(下)
43 | bufio包中的数据类型(下)
讲述:黄洲君
时长11:09大小5.11M
知识扩展
问题 :bufio.Reader类型读取方法有哪些不同?
总结
思考题
赞 12
提建议
精选留言(18)
- xyz2018-11-20慢慢追上了(不过有些内容学的比较粗略……),感觉郝林老师的这个系列,特别是后面的内容更适合作为一个了解常用库的索引存在,有在实际工作中碰到了问题再来参考会更好理解。共 1 条评论18
- wang jl2019-10-11我就想看bufio.Scanner才买的这个教程😓结果是思考题共 1 条评论16
- moonfox2021-06-08可以把 io.Reader 或 strings.NewReader 想像成一个实际的存在于硬盘之上的文件IO对象,你要对这个文件进行读写操作,感觉这样比较生动具体,可以更好的理解bufio包的功能用途,bufio包可以有效的降低系统IO的读写次数,从而提高了程序的性能。 XD5
- 趣学车2020-11-20bufio.Scanner 通过一个分隔函数,循环读取底层读取器中的内容,每次读取一段,使用Scanner.Scan() 读取, 通过Scanner.Text() 或 Scanner.Bytes() 获取读到的内容5
- 乖,摸摸头2020-03-11好吧,看了源码, writer2.ReadFrom 只有缓冲区为0才会跨过缓冲区3
- 张剑2019-08-19先学一遍 有个整体的分类和粗略了解 以后有用到还可回来找到3
- 授人以🐟,不如授人...2021-04-17郝老师,我通过阅读这部分的源代码感受到源代码作者的用心良苦,以及对 I/O 读写控制的精细。我的疑问时:对于方法返回值的用途,以及在设计 API 时,特别是方法的返回值都有哪些需要注意的地方。
作者回复: 简单说,如果是单独的API,那么起码需要明确体现返回值的含义,以及在出现错误或异常情况下的具体行为。 如果是成体系的API,那就要遵循完整统一的规范了。这个规范可以根据项目的实际情况、团队的既有习惯和风格自己定义,比如:返回值文档的写法、返回值的命名方法、多返回值的次序、多返回值的联合赋值方式(如“若err不为nil则ret必为0”之类的)等等。 制定这类规范的时候可以多参考Go标准库中的代码和文档,努力做到自有规范与官方规范的基本一致性。这样做对跨团队协作会更加友好。
3 - 授人以🐟,不如授人...2021-04-17「bufio.Reader类型的 Peek 方法有一个鲜明的特点,那就是:即使它读取了缓冲区中的数据,也不会更改已读计数的值。」这里需要说明的是 Peek 方法可能会修改 b.r 和 b.w 的值,但是对于 Peek 方法来说,其含义是并非是一种“真实”的读取,意味着接下来再用 ReadByte 还能读取到相同的数据。比如用下面的示例程序可以验证: func main() { buf := bytes.NewBufferString("abcd") reader := bufio.NewReader(buf) slice, err := reader.Peek(4) if err != nil { log.Fatal(err) } fmt.Printf("%v.\n", slice) value, err := reader.ReadByte() fmt.Printf("%v.\n", value) }展开3
- Richard2019-12-21“ ReadSlice方法会先在其缓冲区的未读部分中寻找分隔符。如果未能找到,并且缓冲区未满,那么该方法会先通过调用fill方法对缓冲区进行填充,然后再次寻找,如此往复。” 虽然通过后续内容了解了ReadSlice方法只填满一次缓冲区,但是这里上下文中的 “如此反复” 一词容易让人产生和readbyte功能一样的误解。
作者回复: “填充”和“填满”是有区别的。
1 - jxs12112021-10-09请教一个读代码是遇到的疑问,collectFragments方法中fullBuffers并没有提前声明,这样也可添加buff吗吗,另外注释中说这种方式可以减少调用时的内存开销和数据拷贝,是指这里分片拷贝后一次填充到一个切片中返回,就不用外部调用者自己去组装的意思吗
作者回复: 第一个问题,fullBuffers 在 collectFragments 方法中代表了一个有名的结果啊。 它的声明已经包含在该方法的签名中了: collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) 函数或方法签名中的有名结果会在该函数或方法被调用时自动地创建并初始化,其初始化值会是其类型的零值。 第二个问题,你说的对。 collectFragments 方法其实是在做二次缓存,不论读取成功还是出错,都先用“(动态)结构化”的方式把扫描过的数据缓存下来,但把“成败”的判定权留给调用它的代码。更确切地说,是留给 collectFragments 方法的调用方的调用方。 这相当于:“我”在内部把比较繁杂以及容易造成(空间或时间)浪费的那部分操作先做了,正所谓“内置了最佳实践”,至于操作结果的解读“你们”自己做吧。
- lesserror2021-08-29大家一定要看看老师写的示例代码,写的非常用心了。
- 慢动作2021-06-14这几节感觉直接看api或源码就好,没有什么印象深刻的地方
作者回复: 那祝贺你,说明你已经熟知这些知识点了。
共 3 条评论 - 乖,摸摸头2020-03-11basicWriter3 := &strings.Builder{} reader2 := strings.NewReader("1234456789") writer2 := bufio.NewWriterSize(basicWriter3,3) writer2.WriteString("abcd") //此时缓冲区中还有数据 d, basicWriter3的数据为 ”abc“ writer2.ReadFrom(reader2) //这一步不经过缓冲区 //basicWriter3.String() 数据理论上就应该是 abc123456789 //实际我打印出来的数据为 abcd1234567 writer2.Flush() //应该是 abc123456789d 才对,但是实际打印出来并不是这样的展开
- John2019-09-15打卡
- jimmy2019-08-05坚持,加油
- 曾春云2019-06-26每天坚持一课
- Zero2019-04-08坚持
- 虢國技醬2019-03-13打卡