🥇 Pipes
🍿 ¿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