Pipe - это канал, который связывает поток для чтения и поток для записи и позволяет сразу считать из потока чтения в поток записи. Для чего они нужны? Возьмем, к примеру проблему копирования данных из одного файла в другой.
Пусть в папке проекта определен некоторый файл hello.txt. Скопируем его содержимое в новый файл some.txt:
const fs = require("fs"); const readableStream = fs.createReadStream("hello.txt"); const writeableStream = fs.createWriteStream("some.txt"); readableStream.on("data", function(chunk){ writeableStream.write(chunk); });
Данный код вполне работоспособен, и после запуска файла в папке проекта появится новый файл some.txt.
Однако задача записи в поток данных, считанных из другого потока, является довольно распространенной, и в этом случае pipes или каналы позволяют нам сократить объем кода:
const fs = require("fs"); const readableStream = fs.createReadStream("hello.txt"); const writeableStream = fs.createWriteStream("some2.txt"); readableStream.pipe(writeableStream);
У потока чтения вызывается метод pipe(), в который передается поток для записи.
Рассмотрим другую проблему - архивацию файла. Здесь нам надо сначала считать файл, затем сжать данные и в конце записать сжатые данные в файл-архив. Pipes особенно удобно применять для подобного набора операций:
const fs = require("fs"); const zlib = require("zlib"); const readableStream = fs.createReadStream("hello.txt"); const writeableStream = fs.createWriteStream("hello.txt.gz"); const gzip = zlib.createGzip(); readableStream.pipe(gzip).pipe(writeableStream);
Для архивации подключается модуль zlib. Каждый метод pipe() в цепочке вызовов возвращает поток для чтения, к которому опять же можно применить метод pipe() для записи в другой поток.