Go bufio:带缓冲的I/O操作
学习使用bufio包减少系统调用、提高读写效率,包括Scanner、Reader和Writer。 · 难度:入门 · +15XP
bufio:缓冲I/O
直接使用os.File进行小量读写会产生大量系统调用,效率低下。bufio包通过内存缓冲减少系统调用次数,大幅提升性能。
1. bufio.Reader
包装一个io.Reader,提供缓冲读取和便捷方法:
f, _ := os.Open("data.txt")
defer f.Close()
r := bufio.NewReader(f)
// 按行读取
for {
line, err := r.ReadString('
')
if err == io.EOF {
break
}
fmt.Print(line)
}
| 方法 | 说明 |
|---|---|
| ReadByte() | 读取单个字节 |
| ReadString(delim) | 读取直到分隔符 |
| Peek(n) | 查看后续n字节而不移动位置 |
2. bufio.Writer
提供缓冲写入,需要调用Flush()将缓冲数据真正写入底层Writer:
f, _ := os.Create("output.txt")
w := bufio.NewWriter(f)
w.WriteString("Hello, bufio!")
w.Flush() // 重要:刷新缓冲3. bufio.Scanner(最常用)
专为按行、按单词、按自定义分隔符读取设计:
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := scanner.Text()
if line == "exit" {
break
}
fmt.Println("Echo:", line)
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading error:", err)
}4. 缓冲区大小
默认缓冲区大小4096字节,可通过bufio.NewReaderSize自定义:
r := bufio.NewReaderSize(f, 1024*64) // 64KB缓冲区5. 性能对比
// 无缓冲:每次写入触发系统调用
f.Write([]byte("small data")) // 慢
// 有缓冲:积累到一定量再写入
w := bufio.NewWriter(f)
w.Write([]byte("small data")) // 快
w.Flush()
6. 练习提示
下方代码中,使用bufio.Scanner从标准输入读取多行文本,统计并输出总行数和总字符数(不包括换行符)。提示:len(scanner.Text())计算每行字符数。