En la lección anterior aprendiste a leer archivos con readFile. Esa función carga el archivo entero en memoria antes de hacer nada con él. Para un archivo de 1 KB, perfecto. Pero ¿qué pasa con un archivo de 2 GB?
Tu programa intentaría meter 2 GB en la RAM y probablemente colapsaría. Ese es el problema que resuelven los streams.
Imagina que necesitas llenar una piscina. Tienes dos opciones:
Los streams procesan datos por partes (llamadas chunks). En vez de esperar a tener todo, tu programa empieza a trabajar con el primer trozo mientras el resto sigue llegando.
Cada vez que llega un trozo de datos, se dispara el evento data. Cuando ya no hay más datos, se dispara end.
Observa algo interesante: aquí usamos require("node:fs") sin /promises, porque los streams usan eventos, no promesas. Es otra forma de trabajar con operaciones asíncronas en Node.
La función más elegante de los streams es pipe. Conecta un stream de lectura con uno de escritura, como conectar dos tuberías:
Con una sola línea, pipe lee del archivo original y escribe en el destino, trozo a trozo, sin cargar todo en memoria. Es la forma más eficiente de copiar o transformar archivos grandes.
Node tiene cuatro tipos de streams:
| Tipo | Qué hace | Ejemplo |
|---|---|---|
| Readable | Leer datos | fs.createReadStream() |
| Writable | Escribir datos | fs.createWriteStream() |
| Duplex | Leer y escribir | Sockets de red |
| Transform | Modificar datos al pasar | Compresión, cifrado |
Los más comunes en el día a día son Readable y Writable. Los otros los encontrarás en casos más avanzados.
La regla es sencilla:
readFile es más simpleNo siempre lees de un archivo. A veces quieres crear un stream desde datos que ya tienes:
Readable.from convierte un array (o cualquier iterable) en un stream. Es útil para testing o para crear datos de prueba.
createReadStream o Readable.fromdata o usa pipenode index.js en la terminalLos streams son la razón por la que Node.js puede manejar millones de conexiones sin romperse. Es el superpoder del I/O eficiente.