使用 bufio 包通过内存缓冲区批量读写,减少系统调用次数;读取推荐 64KB 缓冲区配合按行读取,写入需调用 Flush 确保数据落盘。
在 Go 中优化文件读写性能,核心是减少系统调用次数、降低 I/O 等待开销,并合理利用 CPU 和磁盘带宽。缓冲(bufio)解决小粒度读写的 syscall 开销,并发处理则适用于多文件或大文件分块场景—
—但要注意:单个文件的顺序读写加 goroutine 并不会提速,反而可能因调度和锁竞争变慢。
直接调用 file.Read() 或 file.Write() 每次都触发系统调用,频繁读取小数据(如逐行、逐字节)时性能极差。bufio 通过内存缓冲区批量操作,显著减少 syscall 次数。
bufio.NewReaderSize(file, 64*1024) 设置 64KB 缓冲区(常见磁盘页大小),再配合 ReadString('\n') 或 ReadBytes('\n') 高效按行处理bufio.NewWriterSize(file, 1(64KB),写完务必调用 w.Flush(),否则内容可能滞留在缓冲区
os.File 原生方法和 bufio,易导致读写位置错乱当需批量处理大量独立文件(如日志归档、图片缩放、CSV 解析),可为每个文件启动 goroutine,配合 sync.WaitGroup 控制生命周期。
sem := make(chan struct{}, 10))控制最大 10 个 goroutine 同时运行,防内存暴涨或磁盘 IO 打满处理 GB 级单文件时,一次性加载到内存不可行。应分块读取(如每次 1MB),并复用字节切片避免高频 GC。
file.ReadAt(buf, offset) 随机读取指定偏移,适合并行分块(注意:需确保文件不被其他进程修改)var bufPool = sync.Pool{New: func() interface{} { return make([]byte, 0, 1,每次从池中取缓冲,用完 bufPool.Put(buf)
file.WriteAt(buf, offset) 并发写(仅限支持随机写的文件,且需保证 offset 不重叠)极端场景(如数据库、高性能存储服务)需要绕过内核 page cache,直接与磁盘交互,避免 double buffering。但这要求:
syscall.Mmap 或 alignedalloc 分配syscall.O_DIRECT(Linux)打开,且每次读写偏移和长度必须对齐