bufio.Scanner 是 Go 标准库中的一个类型,用于高效地逐行读取输入,通常用于处理来自文件、标准输入或其他 I/O 源的流式数据。它的主要功能是将输入按行或自定义分隔符进行分割,便于逐行或逐段处理数据。下面是关于 bufio.Scanner 的简单介绍。

1. 基本用法

创建 Scanner

要使用 bufio.Scanner,首先需要创建一个 Scanner 实例。通常,使用 bufio.NewScanner 函数将一个实现了 io.Reader 接口的对象作为参数传递给 NewScanner

file, err := os.Open("filename.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

scanner := bufio.NewScanner(file)

上面的代码中,file 是一个实现了 io.Reader 接口的 *os.File 对象。

逐行扫描

创建 Scanner 实例后,可以使用 ScannerScan 方法逐行读取输入。每调用一次 Scan,Scanner 会读取下一行的数据。

for scanner.Scan() {
    line := scanner.Text()  // 获取当前行的文本
    fmt.Println(line)
}

Scan 方法会返回 false,当到达输入的末尾或遇到错误时,结束循环。

错误处理

在扫描过程中,可以使用 Err 方法来检查是否发生了错误。

if err := scanner.Err(); err != nil {
    log.Fatal(err)
}

2. 自定义分隔符

默认情况下,Scanner 使用换行符 (\n) 作为分隔符,将输入按行分割。但你可以通过 Split 方法自定义分隔符。

Go 提供了一些内置的分隔函数,例如:

  • bufio.ScanLines:按行分割,这是默认的行为。
  • bufio.ScanWords:按单词分割。
  • bufio.ScanRunes:按 Unicode 字符分割。
  • bufio.ScanBytes:按字节分割。

你也可以实现自己的分隔函数,分隔函数的签名如下:

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

例如,如果你想按空格分割输入,可以使用:

scanner.Split(bufio.ScanWords)

3. 缓冲区大小

默认情况下,Scanner 使用的缓冲区大小为 64 KB。如果需要处理更大的单行输入,可以使用 Buffer 方法来调整缓冲区大小。

buf := make([]byte, 0, 1024*1024) // 1 MB
scanner.Buffer(buf, 1024*1024)

Buffer 方法的第一个参数是用作缓冲区的字节切片,第二个参数是缓冲区的最大大小。

4. 完整示例

下面是一个完整的示例,展示了如何使用 Scanner 逐行读取文件并处理每一行:

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
)

func main() {
    file, err := os.Open("filename.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    
    // 使用自定义分隔符,例如按空格分割
    // scanner.Split(bufio.ScanWords)

    for scanner.Scan() {
        line := scanner.Text()
        fmt.Println(line)
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
}

5. 注意事项

  • Scanner 的缓冲区大小是有限的,如果行的长度超过缓冲区大小,默认情况下 Scanner 会返回错误。对于超大输入,请考虑使用 bufio.Reader 结合 ReadLine 或者其他方式读取。
  • Scanner 不适合处理需要一次性加载到内存中的非常大的输入数据,因为它只能按行或分隔符处理。

6. 小结

bufio.Scanner 提供了一种简单高效的方式来逐行读取数据,非常适合用于读取和处理文本文件或从标准输入读取命令行输入。在需要按行或按自定义分隔符读取输入时,bufio.Scanner 是一个非常有用的工具。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特