Módulo Buffer de Node.js
Módulos incorporados de Node.js
Buffer es una clase en Node.js utilizada para manejar flujos de datos binarios. En una computadora, todos los datos se almacenan y transmiten en forma binaria. Buffer proporciona una manera eficiente de manejar estos datos binarios crudos en Node.js.
Puedes imaginar Buffer como un "contenedor" de tamaño fijo, diseñado específicamente para almacenar datos binarios crudos. A diferencia de los arrays normales de JavaScript, Buffer asigna bloques de memoria de tamaño fijo, lo que lo hace más eficiente al manejar grandes cantidades de datos binarios.
¿Por qué se necesita Buffer?
En el desarrollo web, a menudo necesitamos manejar varios tipos de datos binarios, por ejemplo:
- Operaciones de lectura y escritura de archivos
- Transmisión de datos en comunicaciones de red
- Procesamiento de imágenes
- Operaciones de cifrado y descifrado
JavaScript fue diseñado originalmente principalmente para operaciones DOM en navegadores, con capacidad limitada para manejar datos binarios. Node.js, como runtime de servidor, necesita una capacidad más potente para el procesamiento de datos binarios, razón por la cual existe el módulo Buffer.
Crear Buffer
En Node.js hay varias formas de crear un Buffer:
1. Usar Buffer.alloc()
Ejemplo
const buf1 = Buffer.alloc(10);
console.log(buf1); // <Buffer 00 00 00 00 00 00 00 00 00 00>
2. Usar Buffer.allocUnsafe()
Ejemplo
// Puede contener datos antiguos, por lo que es más rápido pero menos seguro
const buf2 = Buffer.allocUnsafe(10);
console.log(buf2); // <Contenido del Buffer incierto>
3. Crear a partir de un array
Ejemplo
const buf3 = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
console.log(buf3); // <Buffer 62 75 66 66 65 72>
4. Crear a partir de una cadena
Ejemplo
const buf4 = Buffer.from('Hello Node.js');
console.log(buf4); // <Buffer 48 65 6c 6c 6f 20 4e 6f 64 65 2e 6a 73>
Métodos comunes de Buffer
Escribir datos
Ejemplo
// Escribir una cadena
buf.write('Hello');
console.log(buf); // <Buffer 48 65 6c 6c 6f>
// Especificar la codificación al escribir
const buf2 = Buffer.alloc(10);
buf2.write('Hola', 'utf8');
console.log(buf2); // <Buffer e4 bd a0 e5 a5 bd 00 00 00 00>
Leer datos
Ejemplo
// Leer como cadena
console.log(buf.toString()); // Hello World
// Leer parte del contenido
console.log(buf.toString('utf8', 0, 5)); // Hello
Copiar Buffer
Ejemplo
const buf2 = Buffer.from('World');
const buf3 = Buffer.alloc(10);
buf1.copy(buf3, 0); // Copiar buf1 al inicio de buf3
buf2.copy(buf3, 5); // Copiar buf2 a la posición que comienza en el byte 5 de buf3
console.log(buf3.toString()); // HelloWorld
Concatenar Buffer
Ejemplo
const buf2 = Buffer.from(' ');
const buf3 = Buffer.from('World');
const result = Buffer.concat([buf1, buf2, buf3]);
console.log(result.toString()); // Hello World
Buffer y cadenas
Buffer y cadenas se pueden convertir entre sí, pero hay que prestar atención a la codificación. Las codificaciones comunes son:
- 'utf8' (predeterminado)
- 'ascii'
- 'base64'
- 'hex'
Ejemplo
Ejemplo
const str = 'Hello Buffer';
const buf = Buffer.from(str);
// Convertir Buffer a cadena
console.log(buf.toString()); // Hello Buffer
// Usar diferentes codificaciones
console.log(buf.toString('hex')); // 48656c6c6f20427566666572
console.log(buf.toString('base64')); // SGVsbG8gQnVmZmVy
Aplicaciones prácticas de Buffer
1. Operaciones con archivos
Ejemplo
// Leer archivo a Buffer
fs.readFile('example.txt', (err, data) => {
if (err) throw err;
console.log(data); // <Buffer ...>
console.log(data.toString()); // Contenido del archivo
});
// Escribir Buffer a archivo
const content = Buffer.from('Hello File System');
fs.writeFile('output.txt', content, (err) => {
if (err) throw err;
console.log('Archivo guardado');
});
2. Comunicación de red
Ejemplo
http.createServer((req, res) => {
const chunks = [];
req.on('data', (chunk) => {
chunks.push(chunk); // Recopilar bloques de datos
});
req.on('end', () => {
const body = Buffer.concat(chunks); // Combinar todos los bloques de datos
console.log(`Datos recibidos: ${body.toString()}`);
res.end('Datos recibidos');
});
}).listen(3000);
3. Procesamiento de imágenes
Ejemplo
const sharp = require('sharp');
// Leer imagen a Buffer
fs.readFile('input.jpg', (err, data) => {
if (err) throw err;
// Usar sharp para procesar los datos de imagen en Buffer
sharp(data)
.resize(200, 200)
.toBuffer()
.then(outputBuffer => {
// Escribir el Buffer procesado en un archivo
fs.writeFile('output.jpg', outputBuffer, err => {
if (err) throw err;
console.log('Procesamiento de imagen completado');
});
});
});
Consideraciones
Gestión de memoria: Buffer opera directamente sobre la memoria, asignar un Buffer grande puede afectar el rendimiento de la aplicación.
Seguridad:
Buffer.allocUnsafe()Puede contener datos sensibles, ten cuidado al usarlo.Consistencia de codificación: Asegúrate de usar la misma codificación al convertir entre Buffer y cadenas.
Diferencias de versión: La API de Buffer en versiones antiguas de Node.js (v5.x y anteriores) difiere de las versiones nuevas; se recomienda usar la API más reciente.
Consideraciones de rendimiento: Para el procesamiento de grandes volúmenes de datos, el uso adecuado de Buffer puede mejorar significativamente el rendimiento.
Buffer es el módulo central en Node.js para manejar datos binarios. Comprender su funcionamiento y métodos de uso es esencial para desarrollar aplicaciones Node.js eficientes y confiables.
BufferLista de métodos y propiedades del módulo
BufferEs el módulo central de Node.js para manejar datos binarios. A continuación se muestran los principales métodos y propiedades del módulo Buffer:
Propiedades de la clase Buffer
| Propiedad/Método | Descripción | Versión de introducción |
|---|---|---|
| Buffer.poolSize | Tamaño de la instancia de Buffer interna preasignada (en bytes), modificable | 0.11.3 |
| Buffer.from() | Crear un nuevo Buffer a partir de una cadena, un array o un buffer | 5.10.0 |
| Buffer.alloc() | Crear un Buffer inicializado de un tamaño específico | 5.10.0 |
| Buffer.allocUnsafe() | Crear un Buffer no inicializado de un tamaño específico (más rápido pero inseguro) | 5.10.0 |
| Buffer.allocUnsafeSlow() | Crear un Buffer no inicializado (sin usar el pool de memoria compartida) | 5.12.0 |
| Buffer.isBuffer() | Verificar si un objeto es un Buffer | 0.1.101 |
| Buffer.isEncoding() | Verificar si una codificación es válida | 0.9.1 |
| Buffer.concat() | Combinar un array de Buffers | 0.7.11 |
| Buffer.byteLength() | Devolver la longitud en bytes de una cadena | 0.1.90 |
| Buffer.compare() | Comparar dos Buffers | 0.11.13 |
Métodos de instancia de Buffer
| Método | Descripción | Versión de introducción |
|---|---|---|
| buf.length | Longitud en bytes del Buffer | 0.1.90 |
| buf.write() | Escribir una cadena en el Buffer | 0.1.90 |
| buf.toString() | Decodificar el Buffer como cadena | 0.1.90 |
| buf.toJSON() | Devolver la representación JSON del Buffer | 0.9.2 |
| buf.equals() | Comparar si dos Buffers son iguales | 0.11.13 |
| buf.compare() | Comparar Buffers y devolver el orden de clasificación | 0.11.13 |
| buf.copy() | Copiar datos del Buffer | 0.1.90 |
| buf.slice() | Crear una vista parcial del Buffer | 0.3.0 |
| buf.includes() | Verificar si el Buffer contiene un valor | 5.3.0 |
| buf.indexOf() | Devolver la posición de la primera aparición del valor | 1.5.0 |
| buf.lastIndexOf() | Devolver la posición de la última aparición del valor | 6.0.0 |
| buf.fill() | Rellenar el Buffer con un valor específico | 0.5.0 |
| buf.readUIntLE() | Leer entero sin signo little-endian | 0.5.5 |
| buf.readUIntBE() | Leer entero sin signo big-endian | 0.5.5 |
| buf.readIntLE() | Leer entero con signo little-endian | 0.11.15 |
| buf.readIntBE() | Leer entero con signo big-endian | 0.11.15 |
| buf.readDoubleBE() | Leer número de punto flotante de doble precisión de 64 bits big-endian | 0.11.15 |
| buf.readDoubleLE() | Leer número de punto flotante de doble precisión de 64 bits little-endian | 0.11.15 |
| buf.readFloatBE() | Leer número de punto flotante de 32 bits big-endian | 0.11.15 |
| buf.readFloatLE() | Leer número de punto flotante de 32 bits little-endian | 0.11.15 |
| buf.writeUIntLE() | Escribir entero sin signo little-endian | 0.5.5 |
| buf.writeUIntBE() | Escribir entero sin signo big-endian | 0.5.5 |
| buf.writeIntLE() | Escribir entero con signo little-endian | 0.11.15 |
| buf.writeIntBE() | Escribir entero con signo en big-endian | 0.11.15 |
| buf.writeDoubleBE() | Escribir flotante de doble precisión de 64 bits en big-endian | 0.11.15 |
| buf.writeDoubleLE() | Escribir flotante de doble precisión de 64 bits en little-endian | 0.11.15 |
| buf.writeFloatBE() | Escribir flotante de 32 bits en big-endian | 0.11.15 |
| buf.writeFloatLE() | Escribir flotante de 32 bits en little-endian | 0.11.15 |
| buf.swap16() | Intercambiar el orden de bytes de 16 bits | 5.10.0 |
| buf.swap32() | Intercambiar el orden de bytes de 32 bits | 5.10.0 |
| buf.swap64() | Intercambiar el orden de bytes de 64 bits | 6.3.0 |
| buf.keys() | Crear un iterador de claves de Buffer | 1.1.0 |
| buf.values() | Crear un iterador de valores de Buffer | 1.1.0 |
| buf.entries() | Crear un iterador [índice, byte] | 1.1.0 |
Tipos de codificación
Tipos de codificación compatibles con Buffer:
| Codificación | Descripción |
|---|---|
| utf8 | Caracteres Unicode multibyte |
| utf16le | Caracteres Unicode de 2 o 4 bytes |
| latin1 | ISO-8859-1 |
| ascii | Datos ASCII de solo 7 bits |
| base64 | Codificación Base64 |
| base64url | Codificación Base64 segura para URL |
| hex | Codificación hexadecimal |
| ucs2 | Alias de utf16le |
| binary | Alias de latin1 (obsoleto) |
Ejemplo
const buf1 = Buffer.alloc(10); // Inicializar un Buffer con ceros
const buf2 = Buffer.from('hello'); // Crear desde una cadena
const buf3 = Buffer.from([1, 2, 3]); // Crear desde un array
// Escribir y leer
buf1.write('Node.js');
console.log(buf1.toString('utf8', 0, 6)); // 'Node.js'
// Comparar Buffers
const bufA = Buffer.from('A');
const bufB = Buffer.from('B');
console.log(bufA.compare(bufB)); // -1
// Combinar Buffers
const concatBuf = Buffer.concat([bufA, bufB]);