Streams и Buffer
↑ 6.1 Node.js изнутри · ← Предыдущая · → Следующая
Зачем это на собесе
Как обрабатывать большие файлы и HTTP-тела без загрузки в память.
Объяснение
Buffer — фиксированный блок байт вне кучи V8. Stream — последовательная обработка данных по частям.
| Тип | Пример |
|---|---|
| Readable | fs.createReadStream, HTTP-запрос |
| Writable | fs.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-потоками.
Практика
- Сожмите файл 2 ГБ потоком, контролируя память.
- Постройте конвейер парсинга CSV → фильтрация → запись.
- Отдайте большой файл в HTTP-ответе потоком.
Вопросы с ответами
Что такое backpressure?
Сигнал приёмнику/источнику замедлиться, чтобы данные не накапливались в памяти.
Зачем pipeline вместо pipe?
Он передаёт ошибки, закрывает все потоки и учитывает backpressure.