Go 语言核心 36 讲
郝林
《Go 并发编程实战》作者,前轻松筹大数据负责人
79610 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
Go 语言核心 36 讲
15
15
1.0x
00:00/00:00
登录|注册

43 | bufio包中的数据类型(下)

Flush
ReadString
ReadLine
ReadBytes
ReadSlice
Read
Peek
Writer
Scanner
Reader
数据类型
bufio包
bufio包中的数据类型

该思维导图由 AI 生成,仅供参考

你好,我是郝林,我今天继续分享 bufio 包中的数据类型。
在上一篇文章中,我提到了bufio包中的数据类型主要有ReaderScannerWriterReadWriter。并着重讲到了bufio.Reader类型与bufio.Writer类型,今天,我们继续专注bufio.Reader的内容来进行学习。

知识扩展

问题 :bufio.Reader类型读取方法有哪些不同?

bufio.Reader类型拥有很多用于读取数据的指针方法,这里面有 4 个方法可以作为不同读取流程的代表,它们是:PeekReadReadSliceReadBytes
Reader值的Peek方法的功能是:读取并返回其缓冲区中的n个未读字节,并且它会从已读计数代表的索引位置开始读。
在缓冲区未被填满,并且其中的未读字节的数量小于n的时候,该方法就会调用fill方法,以启动缓冲区填充流程。但是,如果它发现上次填充缓冲区的时候有错误,那就不会再次填充。
如果调用方给定的n比缓冲区的长度还要大,或者缓冲区中未读字节的数量小于n,那么Peek方法就会把“所有未读字节组成的序列”作为第一个结果值返回。
同时,它通常还把“bufio.ErrBufferFull变量的值(以下简称缓冲区已满的错误)”
作为第二个结果值返回,用来表示:虽然缓冲区被压缩和填满了,但是仍然满足不了要求。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

bufio包中的数据类型(下)文章详细介绍了bufio包中的数据类型`bufio.Reader`的读取方法。该类型的读取方法包括`Peek`、`Read`、`ReadSlice`和`ReadBytes`,每种方法都有不同的特点和适用场景。其中,`Peek`方法可以读取缓冲区中的未读字节,而不会更改已读计数的值;`Read`方法在缓冲区中还有未读字节时,会依次拷贝到参数中,并更新已读计数的值;`ReadSlice`和`ReadBytes`方法则是持续地读取数据,直至遇到给定的分隔符。此外,文章还提到了这些方法可能存在的内容泄露安全性问题。同时,文章还简要介绍了`bufio.Writer`类型的`Flush`方法以及其数据写入的特点。总的来说,该文章通过深入讲解`bufio.Reader`类型的各种读取方法及其内部流程,为想要深入了解bufio包的读者提供了有价值的技术内容。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 语言核心 36 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • 授人以🐟,不如授人以渔
    郝老师,我通过阅读这部分的源代码感受到源代码作者的用心良苦,以及对 I/O 读写控制的精细。我的疑问时:对于方法返回值的用途,以及在设计 API 时,特别是方法的返回值都有哪些需要注意的地方。

    作者回复: 简单说,如果是单独的API,那么起码需要明确体现返回值的含义,以及在出现错误或异常情况下的具体行为。 如果是成体系的API,那就要遵循完整统一的规范了。这个规范可以根据项目的实际情况、团队的既有习惯和风格自己定义,比如:返回值文档的写法、返回值的命名方法、多返回值的次序、多返回值的联合赋值方式(如“若err不为nil则ret必为0”之类的)等等。 制定这类规范的时候可以多参考Go标准库中的代码和文档,努力做到自有规范与官方规范的基本一致性。这样做对跨团队协作会更加友好。

    2021-04-17
    3
  • 黑客不够黑
    “ ReadSlice方法会先在其缓冲区的未读部分中寻找分隔符。如果未能找到,并且缓冲区未满,那么该方法会先通过调用fill方法对缓冲区进行填充,然后再次寻找,如此往复。” 虽然通过后续内容了解了ReadSlice方法只填满一次缓冲区,但是这里上下文中的 “如此反复” 一词容易让人产生和readbyte功能一样的误解。

    作者回复: “填充”和“填满”是有区别的。

    2019-12-21
    2
  • jxs1211
    请教一个读代码是遇到的疑问,collectFragments方法中fullBuffers并没有提前声明,这样也可添加buff吗吗,另外注释中说这种方式可以减少调用时的内存开销和数据拷贝,是指这里分片拷贝后一次填充到一个切片中返回,就不用外部调用者自己去组装的意思吗

    作者回复: 第一个问题,fullBuffers 在 collectFragments 方法中代表了一个有名的结果啊。 它的声明已经包含在该方法的签名中了: collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) 函数或方法签名中的有名结果会在该函数或方法被调用时自动地创建并初始化,其初始化值会是其类型的零值。 第二个问题,你说的对。 collectFragments 方法其实是在做二次缓存,不论读取成功还是出错,都先用“(动态)结构化”的方式把扫描过的数据缓存下来,但把“成败”的判定权留给调用它的代码。更确切地说,是留给 collectFragments 方法的调用方的调用方。 这相当于:“我”在内部把比较繁杂以及容易造成(空间或时间)浪费的那部分操作先做了,正所谓“内置了最佳实践”,至于操作结果的解读“你们”自己做吧。

    2021-10-09
  • 慢动作
    这几节感觉直接看api或源码就好,没有什么印象深刻的地方

    作者回复: 那祝贺你,说明你已经熟知这些知识点了。

    2021-06-14
    3
  • xyz
    慢慢追上了(不过有些内容学的比较粗略……),感觉郝林老师的这个系列,特别是后面的内容更适合作为一个了解常用库的索引存在,有在实际工作中碰到了问题再来参考会更好理解。
    2018-11-20
    1
    20
  • wang jl
    我就想看bufio.Scanner才买的这个教程😓结果是思考题
    2019-10-11
    1
    16
  • moonfox
    可以把 io.Reader 或 strings.NewReader 想像成一个实际的存在于硬盘之上的文件IO对象,你要对这个文件进行读写操作,感觉这样比较生动具体,可以更好的理解bufio包的功能用途,bufio包可以有效的降低系统IO的读写次数,从而提高了程序的性能。 XD
    2021-06-08
    6
  • 趣学车
    bufio.Scanner 通过一个分隔函数,循环读取底层读取器中的内容,每次读取一段,使用Scanner.Scan() 读取, 通过Scanner.Text() 或 Scanner.Bytes() 获取读到的内容
    2020-11-20
    6
  • 授人以🐟,不如授人以渔
    「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) }
    2021-04-17
    3
  • 乖,摸摸头
    好吧,看了源码, writer2.ReadFrom 只有缓冲区为0才会跨过缓冲区
    2020-03-11
    3
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部