Qué son buffer en NodeJS, junto con algunos ejemplos simples del trabajo con buffers.
Los buffer son conjuntos de datos en crudo, datos binarios, que podemos tratar en NodeJS para realizar diversos tipos de acciones. Los implementa Node a través de una clase específica llamada Buffer, que era necesaria porque Javascript tradicionalmente no era capaz de trabajar con tipos de datos binarios.
Los buffer son similares a arrays de enteros, en los que tenemos bytes que corresponden con datos en crudo de posiciones de memoria fuera de la pila de V8. Aunque desde Javascript ES6 con los TypedArray ya es posible trabajar con un buffer de datos binarios, NodeJS mantiene su clase Buffer que realiza un tratamiento de la información más optimizado para sus casos de uso.
Entre los casos de uso más populares de la plataforma NodeJS se encuentran muchos en los que los buffer son verdaderos protagonistas, como por ejemplo en la comunicación bidireccional que tenemos cuando manejamos sockets, pero también al manipular imágenes o streams de datos.
En este artículo veremos una breve introducción a los buffer, abordando su creación y uso.
Crear un Buffer
Para trabajar con buffers debemos apoyarnos en la clase Buffer, que es global en NodeJS, por lo que no necesitas hacer el require de ningún módulo para poder usarla. Ten en cuenta que el tamaño de un buffer se establece en el momento de su creación y luego ya no es posible cambiarlo.
Podríamos crear un buffer de diversas maneras, la más sencilla es la siguiente:
var b1 = Buffer.alloc(20);
Esto crea un buffer con tamaño de 20 bytes, en el que no hemos definido su contenido, de modo que cada uno de sus bytes estará inicializado a cero.
Pero ten en cuenta que esta manera de crear un buffer es propia de Node 6 en adelante. Antes el equivalente sería así:
var b1 = new Buffer(20); // obsoleto desde NodeJS 6.0
Si queremos crear un buffer incluyendo ya su contenido podemos usar otros métodos de la clase Buffer, como from().
var b2 = Buffer.from('Mañana más');
El método from() permite crear un nuevo buffer en el que contendremos una cadena de caracteres. Además podemos asignar una codificación, siendo "utf8" la codificación predeterminada.
Escribir un buffer por pantalla
El buffer es una cadena de bytes, en binario, por lo que si lo mostramos por pantalla obtendremos una secuencia de valores que inicialmente pueden no tener mucho sentido:
Por ejemplo con los buffer b1 y b2 creados en el punto anterior, podríamos imprimirlos en pantalla con este código.
console.log('Este es mi buffer inicializado a cero');
console.log(b1);
console.log('----------------------------------------');
console.log('Este es mi buffer creado con un string');
console.log(b2);
Ejecutando esto, obtendremos una salida como esta.
Ahora bien, si lo que queremos es ver la cadena tal cual y no los datos en binario, entonces podemos usar el método toString() del buffer. El buffer "b1" (que no se había inicializado) no pintaría nada por pantalla, así que para probar es mejor hacer el volcado de la cadena que tenemos en "b2".
console.log(b2.toString());
Así nos aparecerá la cadena que tenemos en el buffer, tal cual se había introducido "Mañana más".
Manipular el buffer como un array de enteros
Hemos dicho que un buffer es como un array de enteros, por lo que para manipularlo lo podremos usar como tal.
Cada una de las posiciones del buffer se acceden con un índice numérico, comenzando con el índice cero, como los arrays en general en Javascript.
Si haces esto:
console.log(b2[0]);
Obtienes el valor 77, que en hexadecimal corresponde con el valor 4d y que a su vez es equivalente a la "M".
Podríamos modificar de manera arbitraria varias posiciones de nuestro buffer asignando nuevos valores numéricos y luego imprimirlo de nuevo en pantalla para ver lo que ha pasado.
b2[0] = 46;
b2[2] = 54;
b2[3] = 55;
b2[4] = 77;
console.log(b2.toString())
El resultado que veremos es algo como esto:
Hemos dicho que el valor de la "M" es 77. Por tanto, si queremos machacar todos los caracteres del buffer, colocando en todas sus casillas la letra "M", podríamos hacer algo como esto:
for (var i=0; i<b2.length; i++) {
b2[i] = 77;
}
Conclusión
Hemos adquirido un conocimiento muy superficial de los buffer en NodeJS. De hecho, si miras la documentación de buffer podrás observar que es muy extensa, ofreciendo decenas de métodos para hacer innumerables cosas.
Lo cierto es que, explicados los buffer de manera individual no cobran mucho sentido. En resumen, te permiten tratar información binaria a muy bajo nivel, pero hasta que no nos introduzcamos en otros conceptos de Node, como los streams, no seremos capaces de apreciar su verdadera utilidad.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...