En Node.js, los streams son una forma eficiente de manejar la lectura y escritura de datos de manera asíncrona. Los streams permiten procesar datos en fragmentos en lugar de cargar todo el contenido en memoria, lo que es especialmente útil para manejar archivos grandes o flujos de datos continuos.
Conceptos Clave
- Streams de Lectura (Readable Streams): Permiten leer datos de una fuente.
- Streams de Escritura (Writable Streams): Permiten escribir datos a un destino.
- Streams Dúplex (Duplex Streams): Pueden ser tanto de lectura como de escritura.
- Streams Transform (Transform Streams): Son streams dúplex que pueden modificar o transformar los datos mientras pasan a través de ellos.
Tipos de Streams
Tipo de Stream | Descripción |
---|---|
Readable | Permite leer datos de una fuente. |
Writable | Permite escribir datos a un destino. |
Duplex | Permite tanto leer como escribir datos. |
Transform | Permite modificar los datos mientras se leen o escriben. |
Ejemplo Práctico: Lectura de un Archivo con Streams
Vamos a leer un archivo de texto utilizando un stream de lectura.
Paso 1: Crear un Archivo de Texto
Primero, crea un archivo de texto llamado example.txt
con el siguiente contenido:
Paso 2: Leer el Archivo con un Stream de Lectura
A continuación, vamos a leer el archivo utilizando un stream de lectura en Node.js.
const fs = require('fs'); // Crear un stream de lectura const readableStream = fs.createReadStream('example.txt', { encoding: 'utf8', highWaterMark: 16 // Tamaño del buffer en bytes }); // Manejar el evento 'data' para leer los datos en fragmentos readableStream.on('data', (chunk) => { console.log('Nuevo fragmento recibido:', chunk); }); // Manejar el evento 'end' para saber cuándo se ha terminado de leer el archivo readableStream.on('end', () => { console.log('Lectura del archivo completada.'); });
Explicación del Código
fs.createReadStream('example.txt', { encoding: 'utf8', highWaterMark: 16 })
: Crea un stream de lectura para el archivoexample.txt
. El parámetroencoding
especifica que los datos deben ser leídos como texto UTF-8, yhighWaterMark
establece el tamaño del buffer en 16 bytes.readableStream.on('data', (chunk) => { ... })
: Escucha el eventodata
para recibir los datos en fragmentos (chunks). Cada fragmento se procesa a medida que se recibe.readableStream.on('end', () => { ... })
: Escucha el eventoend
para saber cuándo se ha terminado de leer el archivo.
Ejemplo Práctico: Escritura en un Archivo con Streams
Ahora, vamos a escribir datos en un archivo utilizando un stream de escritura.
Paso 1: Crear un Stream de Escritura
Vamos a escribir datos en un archivo llamado output.txt
.
const fs = require('fs'); // Crear un stream de escritura const writableStream = fs.createWriteStream('output.txt'); // Escribir datos en el archivo writableStream.write('Primera línea de texto.\n'); writableStream.write('Segunda línea de texto.\n'); // Finalizar el stream de escritura writableStream.end(() => { console.log('Escritura en el archivo completada.'); });
Explicación del Código
fs.createWriteStream('output.txt')
: Crea un stream de escritura para el archivooutput.txt
.writableStream.write('Primera línea de texto.\n')
: Escribe la primera línea de texto en el archivo.writableStream.write('Segunda línea de texto.\n')
: Escribe la segunda línea de texto en el archivo.writableStream.end(() => { ... })
: Finaliza el stream de escritura y ejecuta la función de callback cuando la escritura se ha completado.
Ejercicio Práctico
Ejercicio 1: Copiar un Archivo Utilizando Streams
Escribe un programa en Node.js que copie el contenido de example.txt
a un nuevo archivo llamado copy.txt
utilizando streams de lectura y escritura.
Solución
const fs = require('fs'); // Crear un stream de lectura const readableStream = fs.createReadStream('example.txt', { encoding: 'utf8', highWaterMark: 16 }); // Crear un stream de escritura const writableStream = fs.createWriteStream('copy.txt'); // Leer datos del archivo de origen y escribirlos en el archivo de destino readableStream.on('data', (chunk) => { writableStream.write(chunk); }); // Finalizar el stream de escritura cuando se haya terminado de leer el archivo readableStream.on('end', () => { writableStream.end(() => { console.log('Copia del archivo completada.'); }); });
Explicación del Código
- Streams de Lectura y Escritura: Se crean streams de lectura y escritura para
example.txt
ycopy.txt
, respectivamente. - Transferencia de Datos: Los datos leídos del archivo de origen se escriben en el archivo de destino en fragmentos.
- Finalización: El stream de escritura se finaliza cuando se ha terminado de leer el archivo de origen.
Conclusión
En esta sección, hemos aprendido sobre los diferentes tipos de streams en Node.js y cómo utilizarlos para leer y escribir datos de manera eficiente. Los streams son una herramienta poderosa para manejar grandes volúmenes de datos sin consumir demasiada memoria. En el próximo módulo, exploraremos cómo trabajar con el módulo del sistema de archivos en Node.js para realizar operaciones más avanzadas.
Curso de Node.js
Módulo 1: Introducción a Node.js
Módulo 2: Conceptos Básicos
Módulo 3: Sistema de Archivos y E/S
Módulo 4: HTTP y Servidores Web
- Creando un Servidor HTTP Simple
- Manejo de Solicitudes y Respuestas
- Sirviendo Archivos Estáticos
- Enrutamiento
Módulo 5: NPM y Gestión de Paquetes
- Introducción a NPM
- Instalación y Uso de Paquetes
- Creación y Publicación de Paquetes
- Versionado Semántico
Módulo 6: Framework Express.js
- Introducción a Express.js
- Configuración de una Aplicación Express
- Middleware
- Enrutamiento en Express
- Manejo de Errores
Módulo 7: Bases de Datos y ORMs
- Introducción a las Bases de Datos
- Usando MongoDB con Mongoose
- Usando Bases de Datos SQL con Sequelize
- Operaciones CRUD
Módulo 8: Autenticación y Autorización
- Introducción a la Autenticación
- Usando Passport.js
- Autenticación JWT
- Control de Acceso Basado en Roles
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con Mocha y Chai
- Pruebas de Integración
- Depuración de Aplicaciones Node.js
Módulo 10: Temas Avanzados
- Módulo Cluster
- Hilos de Trabajo
- Optimización del Rendimiento
- Construcción de APIs RESTful
- GraphQL con Node.js
Módulo 11: Despliegue y DevOps
- Variables de Entorno
- Usando PM2 para la Gestión de Procesos
- Desplegando en Heroku
- Integración y Despliegue Continuos