¿Qué son los pipes?
Los pipes son formas de conectar 2 streams, es decir, que se escribe en uno a través de la lectura del otro o viceversa.
En el ejemplo anterior utilizamos un callback para conectar ambos streams, y funciona, sin embargo esto es un proceso tan repetitivo que Nodejs provee una forma alternativa para realizar este procedimiento mediante pipes. Es decir podemos crear un pipe function o un pipe stream. También vamos a ver como es posible usar un pipe to variable es decir enviar el stream a una variable.
¿Cómo utilizar pipes para conectar los streams?
Solo basta reemplazar el callback de esta forma.
stream_lectura.pipe(stream_escritura);
Y listo, pipe se aplica sobre un stream de lectura, y se le provee como argumento uno de escritura.
La ventaja de de pipe es que se siempre regresa el resultado “pipeable” (al igual que lo hacemos en Linux por ejemplo).
Ejemplo de un pipe para comprimir un archivo en Nodejs
-
Vamos a cargar la librería zlib.
var zlib = require("zlib");
-
Tenemos que proveer a pipe un stream, en este caso un stream que vaya comprimiendo los chunks que vamos leyendo con la librería gzip.
var gzip = zlib.createGzip();
-
Entonces lo podemos encadenar con un pipe.
stream_lectura.pipe(gzip);
Pero hay un problema, el gzip se va a generar, pero no se escribe en ninguna parte. Si deseamos que se escriba tenemos que utilizar un stream de escritura…
¿Cómo encadenar pipes con Nodejs?
Vamos a crear otro stream de escritura que vamos a utilizar de manera encadenada.
-
Definimos el archivo compreso.
var archivo_compreso = __dirname + "/text_destino.txt.gz";
-
Creamos otro stream para escribir el archivo.
var stream_compreso = fs.createWriteStream(archivo_compreso);
-
Hacemos el encademamiento.
stream_lectura.pipe(gzip).pipe(stream_compreso);
Como comentamos pipe regresa un objeto, este objeto tiene también el método pipe y por ende se puede utilizar esta sintaxis encadenada.
Al final nuestro ejemplo quedará así.
var fs = require("fs"); var zlib = require("zlib"); // path al archivo origen var archivo_origen = __dirname + "/texto.txt"; // tamaño del chunk var tamano_chunk = 16 * 1024; // definir el stream de lectura var stream_lectura = fs.createReadStream(archivo_origen, { encoding: "utf8", highWaterMark: tamano_chunk, }); // definir el archivo destino var archivo_destino = __dirname + "/texto_destino.txt"; // crear stream de escritura var stream_escritura = fs.createWriteStream(archivo_destino); // definir el archivo compreso var archivo_compreso = __dirname + "/text_destino.txt.gz"; // crear stream del archivo compreso var stream_compreso = fs.createWriteStream(archivo_compreso); // vamos a decirle a donde hacer el pipe var gzip = zlib.createGzip(); // emisor del stream de lectura stream_lectura.pipe(stream_escritura); // escribir al archivo compreso stream_lectura.pipe(gzip).pipe(stream_compreso);
Zless
-
Vamos ejecutar nuestro código para generar el archivo comprimido.
node app.js
-
Para poder abrir el archivo generado no podemos usar comandos como
cat
oless
, esto se debe a que para ello tendríamos que descomprimir el archivo, por ello es necesario que echemos mano de un comando como zless.zless text_destino.txt.gz