Canais Pipe em Node.js
Pipe é um canal que conecta um fluxo de leitura a um fluxo de escrita, permitindo ler diretamente do fluxo de leitura para o fluxo de escrita. Para que eles são úteis? Vamos considerar, por exemplo, o problema de copiar dados de um arquivo para outro.
Suponha que há um arquivo chamado hello.txt
na pasta do projeto. Vamos copiar seu conteúdo para um novo arquivo chamado some.txt
:
const fs = require("fs");
const readableStream = fs.createReadStream("hello.txt");
const writableStream = fs.createWriteStream("some.txt");
readableStream.on("data", function (chunk) {
writableStream.write(chunk);
});
Esse código funciona corretamente e, após a execução, um novo arquivo some.txt
aparecerá na pasta do projeto.
No entanto, a tarefa de gravar em um fluxo dados lidos de outro fluxo é bastante comum. Nesse caso, os pipes ou canais nos permitem reduzir o volume de código:
const fs = require("fs");
const readableStream = fs.createReadStream("hello.txt");
const writableStream = fs.createWriteStream("some2.txt");
readableStream.pipe(writableStream);
No fluxo de leitura, chamamos o método pipe()
, passando o fluxo de escrita como argumento.
Vamos considerar outro problema: a compactação de um arquivo. Aqui, precisamos primeiro ler o arquivo, depois comprimir os dados e, finalmente, gravar os dados comprimidos em um arquivo de arquivamento. Os pipes são especialmente convenientes para esse conjunto de operações:
const fs = require("fs");
const zlib = require("zlib");
const readableStream = fs.createReadStream("hello.txt");
const writableStream = fs.createWriteStream("hello.txt.gz");
const gzip = zlib.createGzip();
readableStream.pipe(gzip).pipe(writableStream);
Para a compactação, conectamos o módulo zlib
. Cada método pipe()
na cadeia de chamadas retorna um fluxo de leitura, ao qual podemos novamente aplicar o método pipe()
para gravar em outro fluxo.