使用bufio包可提升Go语言I/O性能,通过缓冲机制减少系统调用。1. bufio.Scanner适合逐行读取文本,如日志或配置文件,默认按行分割,支持自动扩容缓冲区;2. bufio.Reader提供更细粒度控制,可用于读取指定字节数或分隔符,适用于大文件按块读取;3. bufio.Writer通过缓冲写入减少磁盘操作,需调用Flush确保数据落盘;4. 在标准输入输出中使用Scanner可高效读取用户输入。关键在于根据场景选择合适类型并注意刷新缓冲区。

在Go语言中,bufio 包是处理文件和I/O操作时提升性能的关键工具。它通过引入缓冲机制,减少系统调用次数,从而显著提高读写效率。尤其在处理大文件或频繁的输入输出场景中,使用
bufio.Scanner、
bufio.Reader和
bufio.Writer能带来明显优势。
使用 bufio.Scanner 读取文本行
当需要逐行读取文件内容时,
bufio.Scanner是最简单高效的选择。它默认按行分割数据,适合处理日志、配置文件等文本内容。
示例:从文件中逐行读取并打印
file, err := os.Open("data.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
说明: Scanner 默认缓冲区大小为 4096 字节,可自动扩展。对于超长行,可通过
scanner.Buffer()手动设置最大容量。
立即学习“go语言免费学习笔记(深入)”;
使用 bufio.Reader 灵活读取数据
当需要更细粒度控制读取行为时(如读取特定字节数、读到分隔符),应使用
bufio.Reader。
常见方法包括:
ReadByte()
:读取单个字节ReadSlice('\n'):读到换行符,返回字节切片ReadString('\n'):类似 ReadSlice,但返回字符串
示例:按块读取大文件
reader := bufio.NewReader(file)
buffer := make([]byte, 1024)
for {
n, err := reader.Read(buffer)
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
// 处理 buffer[0:n]
}
使用 bufio.Writer 提高写入性能
频繁调用
Write()直接写文件会产生大量系统调用。使用
bufio.Writer可将数据先写入内存缓冲区,满后一次性刷入磁盘。
示例:批量写入多行数据
file, err := os.Create("output.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
writer := bufio.NewWriter(file)
lines := []string{"line1", "line2", "line3"}
for _, line := range lines {
fmt.Fprintln(writer, line)
}
// 必须调用 Flush,确保数据写入磁盘
if err := writer.Flush(); err != nil {
log.Fatal(err)
}
注意: 忘记调用
Flush()会导致最后部分数据丢失。
标准输入输出中的应用
在命令行程序中,使用
bufio.Scanner读取用户输入更加高效且简洁。
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("请输入内容: ")
if scanner.Scan() {
input := scanner.Text()
fmt.Printf("你输入的是: %s\n", input)
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
基本上就这些。合理使用 bufio 能让Go程序在文件和I/O操作中表现更高效。关键是根据场景选择 Scanner、Reader 或 Writer,并注意缓冲区刷新问题。










