0Pricing
Go Academy · Урок

Потоковая обработка больших файлов

Обрабатывайте файлы без полной загрузки

«Потоковая обработка больших файлов» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Буферизованные средства чтения
  2. Сканеры
  3. Буферизованные средства записи
  4. Потоковая обработка больших файлов
← Назад к Go Academy