在Go语言中,IO操作是不可避免的,但每次读写都直接访问磁盘或网络,效率实在太低!bufio库通过缓冲技术,让IO操作速度提升数倍。
1. 为什么需要缓冲IO?
1.1 什么是缓冲IO
缓冲读写是一种将IO操作分成多个步骤进行的方法,它将输入或输出数据先缓存到内存中,等到缓存区满或达到一定数量时,再一次性将数据写入磁盘或读入内存。
这种方法可以减少系统调用的次数,提高IO操作的效率。
当频繁地对少量数据读写时会占用IO,造成性能问题。golang的bufio库使用缓存来一次性进行大块数据的读写,以此降低IO系统调用,提升性能。
1.2 直接IO vs 缓冲IO
直接IO就像是用勺子一次只能取一滴水,而缓冲IO则是用桶一次性取水,效率自然不同。直接把内容->文件和把内容->缓冲->文件相比,缓冲区好像没有起到作用嘛。
其实缓冲区的设计是为了存储多次的写入,最后一口气把缓冲区内容写入文件。
| IO类型 |
系统调用次数 |
内存使用 |
适用场景 |
| 直接IO |
多 |
少 |
大文件读写 |
| 缓冲IO |
少 |
多 |
频繁的小文件读写 |
2. bufio.Reader:智能读取
2.1 创建bufio.Reader
bufio.Reader类型提供了缓冲读取的功能,它包装了一个io.Reader对象,并提供了一系列的方法用于从缓冲区中读取数据。
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// 从字符串创建Reader
str := "Hello, World!\n"
reader := bufio.NewReader(strings.NewReader(str))
// 从文件创建Reader
file, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer file.Close()
fileReader := bufio.NewReader(file)
// 创建指定缓冲区大小的Reader
customReader := bufio.NewReaderSize(file, 16) // 16字节缓冲区
// 使用Reader读取数据
for {
line, err := reader.ReadString('\n')
if err != nil {
break
}
fmt.Print(line)
}
}
2.2 常用读取方法
bufio.Reader提供了多种读取方法,适应不同场景:
func main() {
str := "Hello, World!\n1234,567"
reader := bufio.NewReader(strings.NewReader(str))
// 1. 读取直到遇到分隔符
line, _ := reader.ReadString('\n')
fmt.Println("ReadString:", line)
// 2. 读取单个字节
b, _ := reader.ReadByte()
fmt.Printf("ReadByte: %c\n", b)
// 3. 预读取(不移动读取位置)
data, _ := reader.Peek(5)
fmt.Println("Peek:", string(data))
// 4. 读取直到遇到逗号
slice, _ := reader.ReadSlice(',')
fmt.Println("ReadSlice:", string(slice))
// 获取缓冲区内可读字节数
fmt.Println("Buffered:", reade

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



