Streams и Buffer

↑ 6.1 Node.js изнутри · ← Предыдущая · → Следующая

По желанию~3 мин чтенияУровень: junior

Зачем это на собесе

Как обрабатывать большие файлы и HTTP-тела без загрузки в память.

Объяснение

Buffer — фиксированный блок байт вне кучи V8. Stream — последовательная обработка данных по частям.

ТипПример
Readablefs.createReadStream, HTTP-запрос
Writablefs.createWriteStream, HTTP-ответ
Duplexсокет TCP
Transformсжатие zlib, шифрование, парсинг
import { pipeline } from "node:stream/promises";
import { createReadStream, createWriteStream } from "node:fs";
import { createGzip } from "node:zlib";
 
await pipeline(
  createReadStream("big.log"),
  createGzip(),
  createWriteStream("big.log.gz"),
);   // корректно обрабатывает ошибки и закрывает потоки

Backpressure — механизм, когда быстрый источник замедляется медленным приёмником: write() возвращает false, нужно дождаться drain. pipeline делает это автоматически.

for await (const chunk of createReadStream("data.csv", { encoding: "utf8" })) {
  // обработка порциями
}

Нюансы и подводные камни

  • pipe() без обработки ошибок оставляет потоки открытыми: используйте pipeline.
  • Чтение всего файла readFile для гигабайт → OOM.
  • Работа с кодировками: границы многобайтных символов могут делиться между чанками (setEncoding).
  • Кэшируйте Buffer.allocUnsafe осторожно: содержит остатки памяти.
  • Веб-стандарт Web Streams доступен в Node.js рядом с Node-потоками.

Практика

  1. Сожмите файл 2 ГБ потоком, контролируя память.
  2. Постройте конвейер парсинга CSV → фильтрация → запись.
  3. Отдайте большой файл в HTTP-ответе потоком.

Вопросы с ответами

Связанные темы