Cargando



Manejo de buffers en Node.js

En este tutorial veremos cómo realizar el manejo de buffers en una aplicación con Node.js para la manipulación de data binaria, de forma tal que podamos hacer un uso adecuado de la misma con el menor esfuerzo posible.


may 20 2015 03:02
Profesional
nov 25 2016 11:36

JavaScript es un lenguaje que posee un buen manejo de strings, pero debido a que inicialmente fue diseñado para el manejo de documentos HTML, no es muy bueno en el manejo de data binaria, de hecho JavaScript no posee un tipo de dato binario como tal, solo contiene números o tipos estructurados.

 

Como ya sabemos Node.js está basado en JavaScript y el mismo puede manejar protocolos de texto como HTTP, donde además puedes utilizar esto para establecer la comunicación con Bases de Datos, manipular imágenes e incluso manejar la manipulación de archivos y debido a lo que comentamos hacer esto con solo strings puede ser bastante complicado.

 

Pero para hacer estas tareas de manipulación de binarios mucho más sencillas, Node.js incluye una implementación de buffer binario, el cual nos permite obtener y setear los bytes de un buffer creado sin mucho problema.

 

Requisitos
Para llevar a cabo los ejercicios propuestos en este tutorial debemos tener una instalación funcional de Node.js en nuestro sistema, podemos darle un vistazo a este tutorial antes de seguir profundizando en este. Es importante también poder tener acceso a un editor de texto enriquecido para hacer la codificación de los ejemplos, podemos utilizar cualquiera con el que nos sintamos cómodos, sin embargo por su facilidad de uso recomendamos Sublime Text o NotePad ++ los cuales además tienen complementos para la sintaxis JavaScript y HTML.

 

Creación del buffer


Para la creación de un buffer, es tan sencillo como que hagamos una nueva instancia a la clase Buffer(). Veamos como creamos un buffer sencillo en base a una codificación UTF-8 de la siguiente forma:
var buf = new Buffer('Hola mundo!');
console.log(buf);
Vamos a ejecutar nuestro ejemplo por consola para ver la respuesta que nos da Node.js en cuanto a la creación de nuestro buffer:

 

buffer-nodejs.jpg

 

Como vemos si imprimimos nuestra variable buf, la respuesta no es quizá la que estábamos esperando, pero debemos recordar que estamos creando una instancia de Buffer y lo que hace esta clase es encodear su contenido de acuerdo a codificación de caracteres en específico.

 

También podemos crear un buffer de strings con otros encodings, el cual será válido siempre y cuando especifiquemos el mismo como segundo argumento, veamos:

var buf2 = new Buffer('9b38kte610la', 'base64');
console.log(buf2);
Como vemos podemos especificar sin ningún problema el encoding, veamos entonces que tipos de encoding son aceptados y sus respectivos identificadores:

 

ascii - ASCII
Este es el tipo de codificación estándar y está limitado por la codificación de caracteres del mismo nombre.

utf8 - UTF-8
Esta es una variable con el encoding que puede representar cada carácter Unicode existente y este es el encoding por defecto de nuestro buffer en el caso de no especificar alguno.

base64 – Base64
Este es un tipo de codificación que es usada para representar data binaria en un tipo de formato string ASCII y es usado mayormente para embeber data binaria en documentos de texto para asegurar que la data se mantenga intacta en el transporte de la misma.

Adicionalmente, si no tenemos el contenido inicial para nuestro buffer y necesitamos crear uno podemos hacerlo especificando la capacidad del mismo, para ello lo hacemos de la siguiente forma:
var buf = new Buffer(1024);
Con esto lo que hacemos es crear un buffer de 1024 bytes para nuestras operaciones a futuro.

 

Manejo de bytes en el buffer


Luego que hemos creado o recibido el buffer, quizá queremos inspeccionar el mismo y cambiar su contenido. Primero para acceder a los bytes dentro del mismo podemos usar los corchetes de la siguiente forma:
var buf = new Buffer('aqui esta el contenido de mi buffer');
console.log(buf[10]);
Si ejecutamos nuestro ejemplo obtendremos la décima posición del buffer, incluso podemos cambiar a la novena posición del buffer y ver el resultado, veamos como luce:

 

buffer-nodejs-2.jpg

 

Como vemos obtenemos bytes aleatorios para las posiciones de nuestro buffer, incluso si necesitamos manipular el contenido de cualquier posición en el mismo podemos hacer algo como lo siguiente:

var buf = new Buffer('aqui esta el contenido de mi buffer nuevo');

buf[2] = 110;
buf[6] = 180;
buf[10] = 90;

console.log(buf[2]);
console.log(buf[6]);
console.log(buf[10]);
Veamos la respuesta por consola de nuestro ejemplo:

 

buffer-nodejs-3.jpg

 

Como vimos pudimos modificar el contenido de ciertas posiciones dentro de nuestro buffer sin mucho problema, además de esto podemos obtener el tamaño de nuestro buffer con la propiedad length de la siguiente forma:

var buf = new Buffer(100);
console.log(buf.length);
Si somos observadores podremos ver que la respuesta de nuestra consola será 100, donde luego de obtener este valor, lo podemos utilizar para iterar sobre nuestro buffer y de esa forma manipular cada posición para obtener el valor de la misma o setear algún valor en específico, veamos un ejemplo sencillo de esto:
var buf = new Buffer(100);
for(var i = 0; i < buf.length; i++) {
buf[i] = i;
}
console.log(buf);
Lo que hicimos en este ejemplo fue crear un nuevo buffer con una capacidad de 100 bytes y luego seteamos cada byte con un valor empezando desde 0 hasta 99, por último veamos la respuesta de la consola cuando ejecutamos nuestro ejemplo:

 

buffer-nodejs-4.jpg

 

 

Extracción de data del buffer


Otra de las características interesantes del buffer, una vez que lo hemos creado o recibido, es poder extraer una porción del mismo. Podemos “picarlo” por decirlo de alguna forma y crear otro buffer más pequeño con esa porción que hemos picado, sin olvidar especificar desde y hasta donde picaremos el mismo, veamos un ejemplo para ilustrar lo que hemos explicado:
var buffer_completo = new Buffer("este es el contenido de mi buffer que vamos a picar");

var buffer_small = buffer_completo.slice(26, 55);

console.log(buffer_small.toString());
Como vemos primero creamos la instancia de nuestro buffer con el contenido inicial, luego con la función slice() especificamos desde y hasta donde vamos a obtener el contenido, asignamos lo que obtenemos a una nueva variable y por último decodificamos el contenido para poder visualizar el contenido de nuestro segundo buffer, veamos la respuesta por consola al ejecutar el ejemplo:

 

buffer-nodejs-5.jpg

 

Es importante mencionar que cuando cortamos un nuevo buffer no estamos utilizando nueva memoria del sistema, este nuevo buffer usa la memoria del padre ya que solo referencia al mismo pero con un inicio y un final diferentes. Esto puede ocasionar algunos problemas si no somos cuidadosos ya que estamos trabajando sobre el mismo buffer, para ello recomendamos trabajar con el método copy para evitar los problemas, el cual veremos a continuación.

 

Copiando un buffer


Como mencionamos, al cortar un buffer podemos obtener algunos problemas sino somos cuidadosos, pero para ello tenemos el método copy, el cual nos permite copiar el contenido de un buffer en un buffer nuevo, utilizando una nueva instancia y un nuevo espacio de memoria, veamos:
var buffer1 = new Buffer("Contenido buffer numero 1, contenido a copiar");
var buffer2 = new Buffer(20);

var objInicio = 0;
var fuenteInicio = 26;
var fuenteFin = 50;

buffer1.copy(buffer2, objInicio, fuenteInicio, fuenteFin);
console.log(buffer2.toString());
Como vemos creamos dos buffer distintos, donde el primero tendrá el contenido y el segundo solo tendrá el tamaño, especificamos el inicio para nuestro segundo buffer, y de igual forma indicamos el inicio y el final para el nuevo buffer que copiaremos, veamos la respuesta de la consola al ejecutar el ejemplo:

 

buffer-nodejs-6.jpg

 

 

Decodificando un buffer


Como vimos en ejemplos anteriores, pudimos imprimir el contenido original de nuestro buffer al utilizar el método toString(), esto lo que se llama es decodificar el buffer, donde al igual que la instancia de la clase Buffer() si no especificamos nada, por defecto lo decodificamos a UTF-8.

 

Incluso podemos hacer una transcodificación de un string UTF-8 a base64 por mencionar un caso, veamos:

var cadenautf8 = 'mi cadena nueva';

var buf = new Buffer(cadenautf8);

var cadenabase64 = buf.toString('base64')

console.log(cadenabase64);
Por último veamos cómo hemos transcodificado nuestra cadena original:

 

buffer-nodejs-7.jpg

 

Con esto finalizamos este tutorial donde aprendimos las maneras de lidiar con data binaria en Node.js gracias a la clase Buffer, la cual nos permite manipular la misma desde su lectura, escritura, obtener pequeños pedazos de ella, copiar la misma a nuevas instancias e incluso transformar ese buffer a nuevos tipos de encoding para su manipulación en nuestros programas.


¿Te ayudó este Tutorial?


1 Comentarios


David Sanz
may 20 2015 13:49

Buen tutorial, gracias.

No esperes más y entra en Solvetic
Deja tus comentarios y aprovecha las ventajas de la cuenta de usuario ¡Únete!

X