Ответ
Для эффективного чтения больших объемов данных в Go, чтобы избежать ошибок нехватки памяти (out-of-memory
), используется потоковое чтение (streaming). Основные инструменты для этого находятся в пакете bufio
.
1. Использование bufio.Scanner
(для построчного чтения)
Это самый простой и предпочтительный способ для чтения текстовых файлов по строкам.
file, err := os.Open("large_log_file.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
// Сканируем файл построчно
for scanner.Scan() {
line := scanner.Text() // Получаем текущую строку
// process(line)
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
2. Использование bufio.Reader
(для чтения по частям/байтам)
Этот способ более гибкий и подходит для бинарных данных или когда нужно читать данные блоками фиксированного размера.
file, err := os.Open("large_binary_file.bin")
if err != nil {
log.Fatal(err)
}
defer file.Close()
reader := bufio.NewReader(file)
buffer := make([]byte, 4096) // Буфер для чтения, например 4KB
for {
// Читаем данные в буфер
n, err := reader.Read(buffer)
if err != nil {
if err == io.EOF { // Если достигнут конец файла, выходим
break
}
log.Fatal(err)
}
// Обрабатываем прочитанный кусок данных (n байт)
// processChunk(buffer[:n])
}
Оба подхода читают файл не целиком, а небольшими частями, что позволяет обрабатывать файлы любого размера при минимальном потреблении оперативной памяти.