使用bufio.Reader按行或块读取大文件可避免内存溢出。1. 按行读取适合文本文件,用Scanner或ReadBytes处理;2. 自定义缓冲区大小提升I/O性能;3. 按固定块读取适用于二进制或超大行文件,控制内存使用。

在Golang中读取大文件时,直接使用 os.ReadFile 会将整个文件加载到内存,容易导致内存溢出。对于大文件,推荐使用 bufio.Reader 按行或按块读取,实现高效且低内存消耗的处理方式。
适用于日志文件、CSV 等以行为单位的文本文件。通过 bufio.NewReader 包装文件句柄,逐行读取内容。
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func readLargeFileByLine(filename string) {
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
// 处理每一行
fmt.Println(line)
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
说明: bufio.Scanner 默认使用 bufio.Reader,每次读取一行,适合大多数场景。默认缓冲区大小为 4096 字节,可自动扩容。
如果文件行较长或希望优化 I/O 性能,可以手动创建带指定缓冲区的 bufio.Reader。
立即学习“go语言免费学习笔记(深入)”;
func readWithCustomBuffer(filename string) {
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
reader := bufio.NewReaderSize(file, 64*1024) // 64KB 缓冲区
buf := make([]byte, 0, 64*1024)
for {
line, err := reader.ReadBytes('\n')
if err != nil && len(line) == 0 {
break // 文件结束
}
buf = append(buf[:0], line...)
// 处理 line 数据(注意:line 包含 \n)
fmt.Printf("Read: %s", string(buf))
}
}
说明: 使用 ReadBytes('\n') 可精确控制换行符读取,配合大缓冲区减少系统调用次数,提高吞吐量。
对于非文本文件或包含极长行的文件,建议使用 Read 方法按固定字节块读取。
func readInChunks(filename string) {
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
reader := bufio.NewReader(file)
chunk := make([]byte, 32*1024) // 32KB 块
for {
n, err := reader.Read(chunk)
if n > 0 {
// 处理 chunk[0:n]
processChunk(chunk[:n])
}
if err != nil {
break
}
}
}
func processChunk(data []byte) {
// 自定义处理逻辑
fmt.Printf("Process %d bytes\n", len(data))
}
说明: 这种方式适用于日志压缩包、视频、数据库导出等大体积文件,避免因单行过长导致内存暴涨。
基本上就这些。根据文件类型选择合适的读取方式,结合 bufio.Reader 能有效控制内存使用,安全地处理 GB 级甚至更大的文件。不复杂但容易忽略的是缓冲区大小和换行符处理细节。
以上就是Golang如何读取大文件_Golang bufio.Reader大文件读取方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号