Потоковая обработка больших файлов
Обрабатывайте файлы без полной загрузки
«Потоковая обработка больших файлов» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Проблема загрузки всех данных
Чтение многогигабайтного файла в память с помощью os.ReadFile может исчерпать RAM. Вместо этого обрабатывайте его как поток: обрабатывайте блоки по мере их поступления.
Концепция потоковой обработки
Потоковая обработка означает, что в каждый момент времени в памяти хранится только небольшое окно данных. В сочетании с буферизацией это позволяет обрабатывать входные данные любого размера, используя постоянный объём памяти.
Построчная обработка с помощью Scanner
Для текста bufio.Scanner, работающий поверх средства чтения, обрабатывает по одной строке независимо от размера файла. Здесь мы имитируем файл с помощью strings.Reader.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
src := strings.NewReader("alpha\nbeta\ngamma")
s := bufio.NewScanner(src)
for s.Scan() {
fmt.Println("processed:", s.Text())
}
}Подсчёт без загрузки всех данных
Можно вычислять статистику по огромному потоку, удерживая в памяти почти ничего.
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
s := bufio.NewScanner(strings.NewReader("a\nbb\nccc"))
total := 0
for s.Scan() {
total += len(s.Text())
}
fmt.Println("total chars:", total)
}Блоки фиксированного размера
Для двоичных данных читайте в буфер фиксированного размера с помощью Read. n сообщает, сколько байт было заполнено.
package main
import (
"fmt"
"io"
"strings"
)
func main() {
src := strings.NewReader("0123456789")
buf := make([]byte, 4)
for {
n, err := src.Read(buf)
if n > 0 {
fmt.Printf("chunk: %s\n", buf[:n])
}
if err == io.EOF {
break
}
}
}io.Copy для потоковой обработки
io.Copy(dst, src) передаёт все данные из средства чтения в средство записи, используя небольшой внутренний буфер, — без полной загрузки.
package main
import (
"io"
"os"
"strings"
)
func main() {
src := strings.NewReader("streamed straight through\n")
io.Copy(os.Stdout, src)
}Объединение буферов средства чтения и средства записи
Оберните оба конца в bufio, чтобы эффективно преобразовывать поток: буферизованное чтение, обработка, буферизованная запись, сброс.
package main
import (
"bufio"
"os"
"strings"
)
func main() {
r := bufio.NewScanner(strings.NewReader("one\ntwo"))
w := bufio.NewWriter(os.Stdout)
defer w.Flush()
for r.Scan() {
w.WriteString(r.Text() + "!\n")
}
}Гарантия постоянного объёма памяти
Поскольку размер буфера фиксирован, использование памяти остаётся неизменным независимо от того, составляет ли входной файл 1 КБ или 1 ТБ. В этом состоит главное преимущество потоковой обработки.
Как избежать распространённых ошибок
- Не вызывайте
os.ReadFileдля огромных файлов - Всегда обрабатывайте
nбайт перед проверкой ошибки - Не забывайте вызывать
Flush()для буферизованных средств записи
Преобразование потока
Здесь мы переводим каждую строку в верхний регистр по мере её прохождения через поток, храня в памяти только одну строку за раз.
package main
import (
"bufio"
"os"
"strings"
)
func main() {
s := bufio.NewScanner(strings.NewReader("hi\nthere"))
w := bufio.NewWriter(os.Stdout)
defer w.Flush()
for s.Scan() {
w.WriteString(strings.ToUpper(s.Text()) + "\n")
}
}Когда использовать потоковую обработку
Используйте потоковую обработку, когда размер входных данных велик или неизвестен либо когда данные можно обрабатывать постепенно. Загружайте всё целиком только для небольших данных с ограниченным размером, которые нужны одновременно.
Быстрая проверка
Проверьте свои знания о потоковой обработке.
Итоги
Вы научились обрабатывать большие объёмы данных, не загружая их целиком.
- Scanner для построчного чтения текста
Readфиксированного размера для двоичных блоковio.Copyдля передачи из потока в поток- Буферизация обоих концов, сброс буферов средств записи, постоянный объём памяти
Часто задаваемые вопросы
Урок «Потоковая обработка больших файлов» бесплатный?
Да — полный текст урока «Потоковая обработка больших файлов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Потоковая обработка больших файлов»?
Обрабатывайте файлы без полной загрузки Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Потоковая обработка больших файлов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Буферизованные средства чтения
- Сканеры
- Буферизованные средства записи
- Потоковая обработка больших файлов