使用bufio.Reader和bufio.Writer可减少系统调用,提升Go中I/O性能:1. 按行读取文件时,bufio.Reader通过缓冲机制降低读操作的系统调用次数;2. 写入频繁小数据时,bufio.Writer批量写入,合并系统调用,提高吞吐量。

在Go语言中,bufio 包提供了带缓冲的I/O操作,能显著提升文件或网络数据读写的性能。直接使用 os.File.Read/Write 或 net.Conn 的基础读写方法时,每次调用都可能触发系统调用,开销较大。而通过 bufio.Reader 和 bufio.Writer,可以减少系统调用次数,提高吞吐量。
当从大文件或网络流中逐行或按块读取数据时,使用 bufio.Reader 能有效减少系统调用。以下是一个按行读取大文件的示例:
package main
import (
"bufio"
"fmt"
"os"
)
func readWithBufio(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
reader := bufio.NewReader(file)
lineNum := 0
for {
_, err := reader.ReadString('\n')
if err != nil {
break
}
lineNum++
}
fmt.Printf("共读取 %d 行\n", lineNum)
return nil
}
func main() {
readWithBufio("large.log")
}
说明: ReadString 方法会从缓冲区查找分隔符,只有缓冲区不足时才触发系统调用读取更多数据。相比无缓冲的 file.Read,性能更高。
频繁写入小块数据会导致大量系统调用。使用 bufio.Writer 可将多个写操作合并为一次系统调用:
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"bufio"
"os"
)
func writeWithBufio(filename string) error {
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
writer := bufio.NewWriter(file)
data := []byte("hello world\n")
for i := 0; i < 10000; i++ {
writer.Write(data)
}
// 必须调用 Flush,确保数据写入底层
return writer.Flush()
}
关键点: Flush() 是必须的,否则缓冲区中的数据可能不会真正写入文件。
默认情况下,bufio.Reader/Writer 使用 4KB 缓冲区。对于特定场景,手动设置大小可进一步优化性能:
reader := bufio.NewReaderSize(file, 32*1024) // 32KB writer := bufio.NewWriterSize(file, 64*1024) // 64KB
例如,在处理日志文件或网络传输大文本时,增大缓冲区可减少I/O次数。但也不宜过大,避免内存浪费。
对于按行处理文本,bufio.Scanner 更简洁且性能良好:
scanner := bufio.NewScanner(file)
scanner.Buffer(nil, 64*1024) // 设置最大行长度和缓冲区
lineCount := 0
for scanner.Scan() {
lineCount++
// 处理 scanner.Text()
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
优势: Scanner 自动处理换行,API 简洁,并可通过 Buffer() 方法扩展缓冲区以支持长行。
基本上就这些。合理使用 bufio 能大幅提升I/O密集型程序的性能,关键是根据数据特征选择合适的缓冲大小,并记得刷新写入缓冲区。不复杂但容易忽略细节。
以上就是Golang bufio缓冲读写与性能优化示例的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号