go newscanner判断文件读取结束_深入理解 Go 标准库之 bufio.Scanner

e8f1aded46b55585fe55c64fa4693f56.png

众所周知,带缓冲的 IO 标准库 一直是 Go 中优化读写操作的利器。对于写操作来说,在被发送到 socket 或硬盘之前,IO 缓冲区 提供了一个临时存储区来存放数据,缓冲区存储的数据达到一定容量后才会被"释放"出来进行下一步存储,这种方式大大减少了写操作或是最终的系统调用被触发的次数,这无疑会在频繁使用系统资源的时候节省下巨大的系统开销。而对于读操作来说,缓冲 IO 意味着每次操作能够读取更多的数据,既减少了系统调用的次数,又通过以块为单位读取硬盘数据来更高效地使用底层硬件。本文会更加侧重于讲解 bufio 包中的 Scanner 扫描器模块,它的主要作用是把数据流分割成一个个标记并除去它们之间的空格。

"foo  bar   baz"

如果我们只想得到上面字符串中的单词,那么扫描器能帮我们按顺序检索出 "foo","bar" 和 "baz" 这三个单词( 查看源码 )

package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {
    input := "foo  bar   baz"
    scanner := bufio.NewScanner(strings.NewReader(input))
    scanner.Split(bufio.ScanWords)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

输出结果:

foo
bar
baz

Scanner 扫描器读取数据流的时候会使用带缓冲区的 IO,并接受 io.Reader 作为参数。

如果你需要在内存中处理字符串或者是 bytes 切片,可以首先考虑使用 bytes.Split 或是 strings.Split 这样的工具集,当处理这些流数据时,bytes 或是 strings 标准库中的方法可能是最简单可靠的。

在底层,扫描器使用缓冲不断存储数据,当缓冲区非空或者是读到文件的末尾时 (EOF) split 函数会被调用,目前我们介绍了一个预定义好的 split 函数,但根据下面的函数签名来看,它的用途可能更加广泛。

func(data []byte, atEOF bool) (advance int, token []byte, err error)

目前为止,我们知道 Split 函数会在读数据的时候被调用,从返回值来看,它的执行应该有 3 种不同情况。

1. 需要补充更多的数据

这表示传入的数据还不足以生成一个字符流的标记,当返回的值分别是 0, nil, nil 的时候,扫描器会尝试读取更多的数据,如果缓冲区已满,那么缓冲区会在任何读取操作前自动扩容为原来的两倍,让我们来仔细看一下这个过程 查看源码

package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {
    input := "abcdefghijkl"
    scanner := bufio.NewScanner(strings.NewReader
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值