No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

脷ltima oportunidad para asegurar tu aprendizaje por 1 a帽o a precio especial

Antes: $249

Currency
$189/a帽o

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscr铆bete

Termina en:

0D
6H
35M
16S

Streams

25/31
Recursos

Aportes 105

Preguntas 26

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Mi aporte de como lo veo:

** Stream**
Podr铆a decirse que un Stream es el proceso de ir consumiendo datos al tiempo en que se reciben. Por ejemplo, cuando vemos un video en Youtube estamos consumiendo datos por medio de streaming (readable stream, porque solo podemos ver los videos mas no editarlos) ya que lo vemos al mismo tiempo en que este se est谩 descargando. de lo contrario habr铆a que esperar a que se descargue el video por completo para poder verlo.

buffer
Si en el caso anterior, mientras vemos el video, fallara el internet, as铆 sea por un segundo, la reproducci贸n se parar铆a instant谩neamente. Pero sabemos que en realidad no es as铆, el video contin煤a reproduci茅ndose por un tiempo mas. Esto es gracias a la implementaci贸n de un buffer el cu谩l es un espacio en memoria ram en donde la informaci贸n proveniente del servidor llega por fragmentos (chunks), para luego ser consumido, y como ese almacenamiento de datos en el buffer se hace a bajo nivel, de forma binaria, el proceso es mucho mas r谩pido de lo que se consume. Es por eso que cuando reproducimos un video en Youtube vemos que este se carga mas r谩pido. (dependiendo del ancho de banda claro est谩)

intentar茅 explicarlo para ver si se entiende de mejor manera que wea pasa en esta parte del c贸digo

const Transform = stream.Transform;

lo que se hace aqu铆 es crear una constante que va a contener la clase Transform, pero鈥 que es lo que hace Transform?.
pues b谩sicamente lo que hace es transformar la secuencia de entrada para que la secuencia de salida sea una diferente. EJ: ( no falta el weon que se lo olvida que las iniciales de los nombres van en May煤sculas, sin embargo tu quieres asegurarte que los nombres en tu pagina web, la Inicial aparezca en May煤scula. entonces es ah铆 donde ocupas el Transform para que la secuencia de entrada la puedas cambiar y produzca una secuencia de salida diferente.)


Bien que aqu铆 pr谩cticamente estas diciendo que sera en esta funci贸n ser谩 donde ejecutaras la transformaci贸n. al colocar Tranform.call(this) estas iniciando el llamado a la tranformacion de tu secuencia datos. y al colocar this estas diciendo que se har谩 dentro del m茅todo Mayus

function Mayus(){
    Transform.call(this);
}

dicho esto pasemos a lo siguiente鈥


bien ac谩 por lo que busque y encontr茅.(porque el que busca encuentra) lo que hace util.inherits(Mayus,Transform); es crear una instancia de la clase Transform y estableci茅ndolo como prototipo a la funci贸n Mayus, tambien adjuntando el EventEmmitter. es decir el Transform.Call(this).
de modo que cada vez que se crea una instancia de la funcion Mayus se ejecutara el fichero.

en pocas palabras para el que sepa PHP o JAVA . es como llamar al metodo super()

util.inherits(Mayus,Transform);

CABE RECALCAR QUE NODE NO RECOMIENDA USAR ESTA FUNCI脫N


bueno bueno que tenemos ac谩.
pero miren justo Mayus.prototype._transform fue posible gracias a la funci贸n de util.inherits(Mayus,Transform) que establec铆a la clase Transform como prototipo de la funci贸n Mayus.

PERO QUE SIGNIFICA ._transform ?
bueno b谩sicamente significa que la transformaci贸n que tu har谩s podr谩 ser personalizada, as铆 es(como mi redacci贸n). es decir que tu veras que cambio o que transformaci贸n le har谩s a la secuencia de datos que estas recibiendo como entrada.

Mayus.prototype._transform=function(chunk,codifi,callback){
     chunkMayus = chunk.toString().toUpperCase();
     this.push(chunkMayus);
     callback();
}

pasemos a lo siguiente鈥


bueno y por ultimo que sucede al final. pues simple
creas una instancia de la funcion Mayus

y bueno por ultimo lo que hace pipe() es limitar el almacenamiento en el buffer para que no haya una sobresaturacion a la hora se pasar la secuencia de los datos


var mayus = new Mayus();

readablesStream.pipe(mayus).pipe(process.stdout);

BUENO RECALCO QUE ESTO LO DESCRIB脥 CON MIS PROPIAS PALABRAS, si hay algo en lo que me equivoco al mencionar pues que comente para que as铆 sepamos bien el error y entendamos bien el concepto

La clase no fue muy provechosa ya que hubo muchos conceptos que no se explicaron antes (ni tampoco en los cursos de Javascript) y que esta vez se usaron pr谩cticamente sin explicaci贸n.

inherits
__transform
.pipe
.call

Saludos, creo que el profesor no entiende muy bien el codigo de la clase, es por eso que no explico muchas partes, creo que es posible simplificar el codigo para que sea mas entendible para todos los estudiantes y no tengan que preocuparse por cosas que no tienen que ver con streams como el prototipo, inherits y etc.

Hay una forma mas simple de escribir este transform:

const { Transform } = require("stream");
const { createReadStream } = require("fs");

const upperCaseTransform = new Transform({
  transform(chunk, encoding, callback) {
    this.push(chunk.toString().toUpperCase());
    callback();
  }
});

const readableStream = createReadStream(__dirname + "/example.txt");

readableStream.pipe(upperCaseTransform).pipe(process.stdout);

Les comparto un sandbox donde pueden verlo funcionando en vivo https://codesandbox.io/s/node-js-forked-5qiff?file=/src/index.js:0-373

Me parece que se complic贸 demasiado para esta transformaci贸n, hizo muchas cosas r谩pidamente con explicaciones muy leves y no se entendi贸 nada desde que empez贸 a hacer el Transform!

Las Streams son colecciones de datos, como matrices o cadenas. La diferencia es que las transmisiones pueden no estar disponibles de una vez y no tienen que caber en la memoria. Esto hace que las transmisiones sean realmente poderosas cuando se trabaja con grandes cantidades de datos, o datos que provienen de una fuente externa o un fragmento a la vez.

const fs = require('fs');
const server = require('http').createServer();

server.on('request', (req, res) => {
  const src = fs.createReadStream('./big.file');
  src.pipe(res);
});

server.listen(8000);

Cuando un cliente solicita ese archivo grande, lo transmitimos un fragmento a la vez, lo que significa que no lo almacenamos en la memoria intermedia.

Streams


Un stream es el proceso de ir consumiendo datos al tiempo que se est谩n recibiendo. En palabras del profesor, es el paso de datos entre un punto y otro.

const fs = require('fs')

let data = ''

let readableStream = fs.createReadStream(__dirname + '/input.txt')

readableStream.setEncoding('UTF8')
readableStream.on('data', chunk => data += chunk)

readableStream.on('end', () => console.log(data))

En estos casos podemos escribir en buffer de la salida del sistema, process.stdout es un buffer de escritura en que empieza a trabajar para generar todo esto.

process.stdout.write('hola')
process.stdout.write('que')
process.stdout.write('tal')

Para usar los streams, podemos usarlos de la siguiente forma

const Transform = stream.Transform

function Upper() {
    Transform.call(this)
}

util.inherits(Upper, Transform)

Upper.prototype._transform = function (chunk, codif, cb) {
    chunkUpper = chunk.toString().toUpperCase()

    this.push(chunkUpper)
    cb()
}

let upper = new Upper()

readableStream
    .pipe(upper)
    .pipe(process.stdout)

El error que tuvimos varios estaba en utilizar el this dentro de una arrow function. En ese caso la funci贸n apunta al objeto Window y no a Mayus.

Antes:

Mayus.prototype._transform = (chunk, codif, cb) => {
  chunkMayus = chunk.toString().toUpperCase();
  this.push(chunkMayus);
  cb();
}

Despues:

Mayus.prototype._transform = function (chunk, codif, cb) {
  chunkMayus = chunk.toString().toUpperCase();
  this.push(chunkMayus);
  cb();
}

En esta clase se us贸 funciones prototipal, he hecho un ejemplo usando las clases de es6 y quedo asi el buffer de transformacion.

/ BUFFER DE TRANSFORMACION
const Transform = stream.Transform;

function Mayus() {
  Transform.call(this)
}

util.inherits(Mayus, Transform);

Mayus.prototype._transform = function(chunk, codif, cb) {
  chunkMayus = chunk.toString().toUpperCase();
  this.push(chunkMayus)
  cb();
}

let mayus = new Mayus();

readableStream.pipe(mayus)
.pipe(process.stdout)

// Haciendolo con clase

class MayusC extends Transform {
  _transform(chunk, codif, cb){
    let chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus)
    cb();
  }
}

let mayusC = new MayusC();
readableStream.pipe(mayusC)
.pipe(process.stdout)

Solo es la parte de LEER
Dentro de poco subo la parte de escribir y la de hacer las dos cosas

Imagina que tienes un dulce enorme que transportar hacia tu casa para que tus hijos coman
Eres muy fuerte pero el dulce es demasiado grande, pero se te ocurre hacer algo traes una canasta y divides el dulce en partes llenas la canasta y env铆as esa canasta a tus hijos as铆 tus hijos pueden ir comiendo los dulces que les enviaste mientras tus hijos se comen los dulces t煤 llenas la 2da canasta y la env铆as, as铆 funciona esto

el b煤fer ser铆a la canasta y streams ser铆a el movimiento de enviar todo

Una vez sabiendo eso continuemos

Trabajaremos con archivos de texto en esta ocasi贸n as铆 que usaremos el m贸dulo fs

const fs = require(鈥榝s鈥)

//Aqu铆 estoy creando una variable que se llama readableStream
//Le decimos que habr谩 la direcci贸n que indicamos y lea el input

let readableStream = fs.createReadStream(__dirname + 鈥/input.txt鈥, 鈥榰tf8鈥)

//Esto disparar un evento cada vez que recibamos datos y en el callback le decimos que queremos hacer con los datos
que van entrando
//(chuck) esto quiere decir una parte de lo que has recibido
//Podemos leer un archivo de 1GB y esperar que lea 1GB y luego nos muestre o
// Podemos decirle tr谩eme el chunk que ya tienes es decir si ya tienes 5mb tr谩elos que ir茅 trabajando con eso

readableStream.on(鈥榙ata鈥, (chunk)=>{

console.log('new chunck recevid:')
console.log(chunk)

})

//Pero donde est谩 la magia en todo esto ?
Pues ver谩s te recomiendo que hagas el archivo input.txt y lo llenes de texto al azar 500 l铆neas de texto 100 lo que t煤 quieras

y veraz como cada vez que se llena el buffer (chunk) nos pasara al callaback donde le dijimos
okay mu茅strame el avance del paquete que ya tienes de todo lo que tienes que mostrarme

Si te ayudo regale un like 馃槈
Te recuerdo que yo tambi茅n estoy aprendiendo esto as铆 que si tienes algo m谩s que aportar estar铆a excelente

Buffer es la forma en que podemos leer los datos es su forma mas sencilla, en este caso Node transmite estos datos Buffer en binario.
Poder convertir datos a Buffer nos ayudara a la velocidad y mejorar el rendimiento de la lectura y escritura de datos, debido que se hace en el lenguaje de m谩s bajo nivel para las maquinas.
Los streams son puntos de lectura de Buffers, con estos podemos declarar que acciones ejecutar cuando se recibe un buffer. Existen tres tipos de streams, stream de lectura, de escritura y de lectura y escritura.
Un gran ejemplo de uso de los streams es el procesamiento de archivos grandes, como im谩genes o videos, ya que podemos transformar estos a buffer y a trav茅s de los streams cargarlos o guardarlos parte por parte para mejorar el rendimiento de nuestro c贸digo.

Tuve que ver diez veces el video a lo largo de una semana y por fin entend铆 todo jaja

Usando ES6 nos evitamos usar util.inherits y hace que sea un poco mas facil de entender

class Mayus extends stream.Transform{
  constructor(){
    super()
  }

  _transform(chunk, codif, cb){
    let chunkMayus = chunk.toString().toUpperCase()
    this.push(chunkMayus)
    cb()
  }
}

Gracias a todos por los aportes, entend铆 mejor la clase despu茅s de leer todos los comentarios

util.inherits est谩 descontinuado. Pero se puede sustituir por la keyword class, de esta forma:

const Transform = stream.Transform;

class Mayus extends Transform {
    _transform(chunk, codif, cb) {
        let chunkMayus = chunk.toString().toUpperCase();
        this.push(chunkMayus);
        cb();
    }
}

let mayus = new Mayus();

readatableStream
    .pipe(mayus)
    .pipe(process.stdout)

La documentaci贸n de Util dice que es mejor usar las keywords de ES6 class y extends, ya que no habr谩 compatibilidad a futuro, les comparto mi soluci贸n usando esta sintaxis:

const Transform = stream.Transform

class Mayus extends Transform{
    _transform(chunk, encoding, callback) {
        const chunkMayus = chunk.toString().toUpperCase()
        this.push(chunkMayus)
        callback()
    }
}

const mayus = new Mayus()

readStream.pipe(mayus).pipe(process.stdout)

const fs = require('fs')
const stream = require('stream')
const util = require('util')

let data = '';
let readableStream = fs.createReadStream(__dirname+'/input.txt')
readableStream.setEncoding('UTF8')
readableStream.on('data',(texto)=> {
    data += texto

})

readableStream.on('end',() => {
    console.log(data)
})

// stream de escritura:
// process.stdout.write('hola')
// process.stdout.write('mundo')

const Transform = stream.Transform;
function Mayus(){
    Transform.call(this)
}
util.inherits(Mayus,Transform)

Mayus.prototype._transform = function(texto,codif,cb){
    textoMayuscula = texto.toString().toLowerCase()
    this.push(textoMayuscula)
    cb()
}
let mayus = new Mayus()
readableStream.pipe(mayus).pipe(process.stdout)

Sobre el uso de .pipe estuve investigando un poco y encontre lo siguiente que creo les puede servir de ayuda para el uso del mismo.

por ejemplo si tienen una funci贸n, donde getName es transformado a mayusculas, luego se seleccionan los prieros 6 caracteres y luego se escribe en reverso como la siguiente, se vuelve un poco complicado de leer:

reverse(get6Characters(uppercase(getName({ name: 'Buckethead' }))));
// 'TEKCUB'

el uso de .pipe lo facilita de la siguiente manera:

pipe(
  getName,
  uppercase,
  get6Characters,
  reverse
)({ name: 'Buckethead' });
// 'TEKCUB'

Es algo que de un articulo de internet y me parecio valioso compartirlo aqui pueden leer el articulo

pipe():sirve para env铆o de datos y formas de env铆o

Hola, hasta ahora excelente el curso. De este video me queda la duda de porque hay que hacer tantos trucos para usar el Stream de transformaci贸n? No parece natural. Gracias.

Lo malo de que dejan de darle mantenimiento a estos cursos es que aprendemos cosas que ya son obsoletas y pcoos nos percatamos de ello F para platzi team

Usage of util.inherits() is discouraged. Please use the ES6

SI no les quedo claro, talvez con las sintaxis de ES6 se entienda mejor, de igual forma pueden leer la documentaci贸n aqu铆

class Mayus extends Transform {
  _transform(chunk, codif, cb) {
    let chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    cb();
  }
}

const mayus = new Mayus();
readableStream.pipe(mayus).pipe(process.stdout);

La peor clase del curso, us贸 muchos conceptos y m贸dulos con poco o cero contexto, para alguien que esta empezando esta clase ser铆a diractamente chino, especialmente para el final

Bueno, no me quer铆a quedar con las ganas de aprender un poco m谩s a fondo este tema de los streams que veo es algo muy potente e importante, as铆 que luego de un par de horas de estudio les puedo compartir lo siguiente lo m谩s resumido y sencillo posible:

Stream de lectura
Un stream de lectura te permite leer datos de una fuente, como un archivo o una solicitud HTTP, y enviarlos a otro lugar, como un stream de transformaci贸n. Aqu铆 tienes un ejemplo de c贸mo crear un stream de lectura para leer datos de un archivo:

let readableStream = fs.createReadStream(__dirname + '/contactos.csv'); // Para leer un archivo csv que les dejar茅 m谩s abajo en el aporte
readableStream.setEncoding('utf8'); // Para esteblecer la codificaci贸n

Ya con esto pueden acceder al contenido 鈥渟treameado鈥 del archivo, sin embargo, por si se preguntaron cu谩l es la capacidad del buffer por defecto del stream, es de 64 KB o por si se preguntaron c贸mo hago para indicarle a mi stream que use otra capacidad espec铆fica, lo pueden hacer de la siguiente manera:

let readableStream = fs.createReadStream(__dirname + '/contactos.csv', {highWaterMark: 32 * 1024});

All铆 le indico que lo haga cada 32 KB. As铆 es, la propiedad del objeto la toma en KB.

Stream de transformaci贸n
Un stream de transformaci贸n te permite modificar los datos que fluyen a trav茅s de 茅l. Por ejemplo, puedes utilizar un stream de transformaci贸n para convertir un archivo CSV en un formato JSON. Aqu铆 tienes un ejemplo de c贸mo crear un stream de transformaci贸n para convertir datos de formato CSV a formato JSON:

const stream = require('stream');
const toUpperTransformStream = new stream.Transform({
    transform(chunk, encoding, callback) {
        try {
            callback(null, Buffer.from(chunk.toString().toUpperCase()));
        } catch (error) {
            callback(error, chunk);
        }
    }
});

La anterior es otra manera de crear streams de transformaci贸n, me gust贸 m谩s esta ya que la que us贸 el profe en el video usa conceptos que quiz谩s algunos desconozcan, como herencia y prototipos en JavaScript. Aqu铆 usamos una clase ya existente para ello (Transform).

Para usar el stream simplemente lo pasan como argumento de la funci贸n pipe del readableStream:

let readableStream = fs.createReadStream(__dirname + '/contactos.csv', {highWaterMark: 64 * 1024})
    .pipe(toUpperTransformStream);

No les voy a poner c贸mo imprimir en consola los datos del stream porque como lo ense帽贸 el profe en el video funciona perfecto y pues es algo sencillo. Si podr铆an probar c贸mo va cambiando la impresi贸n de cada chunck cuando juegan con el tama帽o del buffer, es decir, el valor que le pasan a la propiedad highWaterMark.

Lo que si les voy a dejar es el contenido del archivo CSV que us茅 para mis pruebas, por si les interesa 鉁 De tarea les queda averiguar como funciona el stream de escritura. 脡xitos!

Nombre,Apellido,Edad,Tel茅fono
Miguel,Castillo,25,555-123-4567
Luis,Hern谩ndez,38,555-234-5678
Ana,Ch谩vez,19,555-345-6789
Carolina,G贸mez,47,555-456-7890
Pedro,Mart铆nez,32,555-567-8901
Laura,Flores,27,555-678-9012
Javier,Rodr铆guez,50,555-789-0123
Mar铆a,Torres,23,555-890-1234
Sara,Jim茅nez,41,555-901-2345
Jos茅,P茅rez,36,555-012-3456
Sof铆a,Romero,28,555-123-4567
Daniel,Fern谩ndez,45,555-234-5678
Valentina,S谩nchez,20,555-345-6789
Manuel,Alvarez,49,555-456-7890
Luc铆a,M茅ndez,31,555-567-8901
Diego,Vargas,26,555-678-9012
Ana,Hern谩ndez,23,555-123-4567
Mario,Rodr铆guez,40,555-234-5678
Sof铆a,Castro,32,555-345-6789
Pedro,Vega,26,555-456-7890
Mar铆a,Ju谩rez,44,555-567-8901
Luis,Ram铆rez,31,555-678-9012
Carolina,L贸pez,29,555-789-0123
Roberto,Ruiz,46,555-890-1234
Laura,Escobar,35,555-901-2345
Juan,P茅rez,30,555-012-3456
M贸nica,Galv谩n,37,555-123-4567
Carlos,Flores,33,555-234-5678
Karen,Garc铆a,27,555-345-6789
Jorge,Guzm谩n,39,555-456-7890
Diana,Santos,22,555-567-8901
C茅sar,M茅ndez,42,555-678-9012

Estoy en Twitter y en Instagram como @guillermoplus por si me quieren seguir. 馃懆鈥嶐煉

Espero les sirva Salu2.

Quisiera aportar el siguiente c贸digo usando el class de Javascript:

// ....
const Transform = stream.Transform;

class Mayus extends Transform {
      constructor() {
            super();
            Transform.call(this);
      }
      _transform = (chunk, codif, cb) => {
            let chunkMayus = chunk.toString().toUpperCase();
            this.push(chunkMayus);
            cb();
      };
}

// ...

A m铆 me sirvi贸 para resolver un error que salt贸 en mi consola al intentar usar la versi贸n de esta clase.

馃檪 Saludos y muchos 茅xitos, colegas!

Qu茅 clase m谩s compleja!, pero estuvo rebuena!. Tuve que usar un archivo muy grande para ver con mis propios ojos el tema de los chunks! 馃槃

Not茅 entonces que cada chunk era de aproximadamente 64kb, y ah铆 ya empec茅 a entender mejor el procedimiento.

Est谩 super el curso!

Sintaxis con las clases de ES6

const Transform = stream.Transform;

class Mayus extends Transform {}

Mayus.prototype._transform = function (chunk, encoding, cb) {
  chunkMayus = chunk.toString().toUpperCase();
  this.push(chunkMayus);
  cb();
};

let mayus = new Mayus();

readableStream.pipe(mayus).pipe(process.stdout);

炉\锛(銉)锛/炉

Este c贸digo:

const Mayus = function(){
    stream.Transform.call(this);
}
util.inherits(Mayus, stream.Transform);
Mayus.prototype._transform = function(chunk, codif, cb){
    const chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    cb();
}

Es equivalente a

const Mayus = function(){
    stream.Transform.call(this);
};
Mayus.prototype = Object.create(stream.Transform.prototype);
Mayus.prototype.constructor = Mayus;
Mayus.prototype._transform = function(chunk, codif, cb){
    const chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    cb();
}

Y equivalente a

class Mayus extends stream.Transform{
    constructor(props) {
        super(props);
    }
    _transform(chunk, codif, cb){
        const chunkMayus = chunk.toString().toUpperCase();
        this.push(chunkMayus);
        cb();
    }
}

Por si se confudieron como yo al ver 鈥渦til.inherits鈥, 鈥淿transform鈥
, 鈥.call鈥 . Y todo la implantaci贸n rara (al menos para mi), ac谩 les dejo mi versi贸n usando Clases ES6:

Lo que hacemos es crear una nueva clase 鈥淢ayus鈥 que heder谩 de 鈥淭ransform鈥 que proviene del modulo 鈥渟tream鈥, si no recuerdan para que sirven la funcion super dentro del constructor es para que la clase "Mayus " heder茅 todas las propiedades del objeto 鈥淭ransform鈥, pero en 鈥淢ayus鈥 cambiamos el comportamiento del metodo _transform, el cual es la funcion que va a transformar el contenido del stream por medio de una pipe. Siendo lo mas raro dentro de esta funcion el 鈥渢his.push()鈥 lo cual no es nada mas la forma de devolver una salida legible para los streams (o eso entendi de la documentacion). Aca les dejo parte de la documentacion oficial por si se perdieron con mi explicacion:


鈥淎ll Transform stream implementations must provide a _transform() method to accept input and produce output. The transform._transform() implementation handles the bytes being written, computes an output, then passes that output off to the readable portion using the transform.push() method.鈥

Para cosas muy peque帽as no tiene sentido utilizar un stream, pero t煤 lo haz hecho en el ejemplo. Hubiese sido 煤til con un ejemplo apropiado al caso. Los ejemplos deben servir para ilustrar y aclarar un tema, no dar un mal ejemplo y decir 鈥渆sto no tiene sentido, se usa para otra cosa鈥, se entiende? Para la pr贸xima clase quiz谩s, o si te agrade hacerte cargo y regrabar esta. Gracias.

Stream

Se refiere al paso de datos entre 2 puntos. Existen varios tipos de stream:

  • Stream de lectura: Es donde existe un origen y el stream se encarga de traer datos y podemos gestionarlos como deseemos.
  • Stream de escritura: Es donde tengo datos y mediante el stream mando datos a un destino concreto.
  • Stream de doble sentido (lectura y escritura): Cumple la funci贸n de los dos anteriores.

Stream de lectura

Para crear un stream que sea legible, se debe importar el m贸dulo fs .

const { createReadStream } = require('fs')

Luego de esto, se debe crear obtener los datos o el archivo que contiene el buffer que se debe stremear.

let readableStream = createReadStream(`${__dirname}/input.txt`)

Se puede configurar la codificaci贸n del archivo, para no tener que acudir a m茅todos como toString() , sino que sea algo m谩s org谩nico.

readableStream.setEncoding('utf-8')

Utilizando los m茅todos del stream, se debe escuchar el evento 'data' que permite saber cuando llega nueva informaci贸n, en este caso se hace una funci贸n que mande por consola lo que es obtenido de la 'data' .

readableStream.on('data', (chunk) => {
  console.log(chunk)
})

Para obtener archivos grandes de informaci贸n la siguiente forma es la m谩s adecuada para ir recibiendo los chunks y luego manejarlos.

  1. Se crea una variable que va a ir recibiendo los datos:

    let data = ''
    
  2. En la funci贸n se guarda la informaci贸n que se obtiene en la variable data .

    readableStream.on('data', (chunk) => {
      data += chunk
    })
    
  3. Para saber cuando se termina de recibir la informaci贸n, se hace lo siguiente.

    readableStream.on('end', () => {
      console.log(data)
    })
    

    Esto sirve cuando se trabaja con archivos muy grandes de informaci贸n.

Stream de escritura

Mediante la salida est谩ndar del sistema stdout se puede generar un buffer de escritura, pero no tiene estructura por si mismo.

process.stdout.write('Hola')
process.stdout.write('que')
process.stdout.write('tal')

/*
Output:
Holaquetal
*/

Buffer de transformaci贸n

Se debe importar el m贸dulo stream .

const stream = require('stream')

En este caso se va a convertir un buffer de datos a may煤sculas.

  1. Se debe crear un stream de transformaci贸n mediante una clase que va a heredar de stream.Transform , esto se hace utilizando la sintaxis de EcmaScript6.

    class Mayus extends stream.Transform {
    	_transform(chunk,encode,cb) {
    		let chunkMayus = chunk.toString().toUpperCase()
    		this.push(chunkMayus)
    		cb()
    	}
    }
    
    /*
    Output:
    ESTE 
    ES 
    UN 
    ARCHIVO
    QUE 
    VAMOS 
    A 
    LEER
    */
    

En mi 煤ltima aplicaci贸n tuve que desarrollar la subida de archivos de tipo pdf pero en general funciona para cualquier tipo de archivos.
En ese caso que les platico, realic茅 la funcionalidad con m贸dulos de Stream.
Ustedes, ya de ante mano, realizaron sus configuraciones de Express para el desarrollo API de un backend web.

En nuestras primeras l铆neas, observar谩n una 鈥渃onfiguraci贸n鈥 t铆pica de un fs para obtenera la informaci贸n de recurso fs.createReadStream
En ello, se establece una comunicaci贸n con el Backen, a trav茅s de un endpoint de servicio, para obtener todo ese blob de informaci贸n.
En mi caso, sub铆 la informaci贸n a FireStore para su almacenamiento.

Encontrar谩n el caso donde se limp铆a el nombrado del archivo para evitar acentos o guiones bajos y dejarlo l铆mpio en un solo formato.
Ambos puntos, establecen la comunicaci贸n para que, cuando terminen, ambos se mencionen:

  1. Desde el cliente, ya no tengo m谩s que subir.
  2. Desde el backend, ok (200) ya tengo todo arriba.

Este es el c贸digo del profe con unas cuantas notas explicando lo que hace cada cosa.
utilic茅 aportes de los compa帽eros en los comentarios para entenderlo un poco mejor y aca les dejo mis apuntes por si a alguien le sirve

const fs = require('fs');
const stream = require('stream');
const util = require('util');

let data = '';

//createReadStream me permite generar un stream de lectura
//en este casoestoy tomando un archivo de texto cualquiera como input
let readableStream = fs.createReadStream(__dirname + '/input.txt');

// readableStream ir谩 recibiendo los paquetes o chunks en formato de buffer 
// y en este caso los estoy parceando a utf8
// chunk es como se llama a cada paquete o fragmento de datos que ir茅 leyendo
readableStream.setEncoding('UTF8');

//   readableStream.on('data'...) inicia una escucha de evento en la que escuchar茅
//   cuando reciba la informaci贸n del archivo a leer
//   luego ir茅 a帽adiendo los chunks a mi variable data declarada previamente
// readableStream.on('data', function (chunk) {
//     data += chunk;
// });

//   readableStream.on('end'...) escucha a cuando se termina de recibir datos del archivo
//   de texto. en ese momento hago un consol.log y muestro el total de la data
// readableStream.on('end', function() {
//     console.log(data);
// });

//   Aqu铆 estoy escribiendo en el buffer de la salida del sistema
//   es el ejemplo mas sencillo de stream de escritura
// process.stdout.write('hola')
// process.stdout.write('que')
// process.stdout.write('tal')

// Ya vimos stream de lectura y de escritura ahora veremos la forma media en la que
// leemos la secuencia la transformamos y volvemos a escribir

// lo que se hace aqu铆 es crear una constante que va a contener la clase Transform,
// pero鈥 que es lo que hace Transform?.
// transforma la secuencia de entrada para que la secuencia de salida sea una diferente.
const Transform = stream.Transform;

// en esta funci贸n ser谩 donde ejecutaras la transformaci贸n. al colocar Tranform.call(this)
// estas iniciando el llamado a la tranformacion de tu secuencia datos
// y al colocar this estas diciendo que se har谩 dentro del m茅todo Mayus
function Mayus() {
    Transform.call(this);
}

// util.inherits(Mayus,Transform); es crear una instancia de la clase Transform 
// y estableci茅ndolo como prototipo a la funci贸n Mayus, tambien adjuntando el EventEmmitter.
// es decir el Transform.Call(this).
// de modo que cada vez que se crea una instancia de la funcion Mayus se ejecutara el fichero.
// en pocas palabras para el que sepa PHP o JAVA . es como llamar al metodo super()
util.inherits(Mayus, Transform);

// le agrego una funcion personalizada a mayus (paquete, codificacion, callback)
Mayus.prototype._transform = function(chunk, codif, cb) {
    chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    cb();
}

// aqui es donde comienzo a hacer la trnasformacion, lo anterior era 
// la configuracion o codigo necesario
let mayus = new Mayus();

readableStream // entrada
    .pipe(mayus) // transformacion
    .pipe(process.stdout); //salida

    // pipe() limita el almacenamiento en el buffer para que no haya una 
    // sobresaturacion a la hora se pasar la secuencia de los datos

La implementaci贸n de ejemplo de los stream de transformaci贸n es algo engorrosa, ya que pod铆amos hacer lo mismo en el readableStream con un .toUpperCase() en el evento 鈥榙ata鈥, antes de concatenar el chunk a la variable data.

<h1>Streams<h1>

son colecciones de datos, como matrices o cadenas. La diferencia es que las transmisiones pueden no estar disponibles de una vez y no tienen que caber en la memoria. Esto hace que las transmisiones sean realmente poderosas cuando se trabaja con grandes cantidades de datos, o datos que provienen de una fuente externa o un fragmento a la vez.

<h4>Streams de lectura</h4>
const fs = require('fs');
let data = ""
let stream = fs.createReadStream (__dirname + "./archivo.txt") // importamos un archivo
stream.on("data", (chunk) => {
	console.log(chunk) // veremos el chunk que recibimos
// si son varios chunk usamos data += chunk
// podemos usar stream.setEncoding(UTF8) para convertir a sting
});
// para imprimir una vez terminado
stream.on("exit", (chunk) => {
	console.log(data)
}); // cuidado con las arrow function aqu铆 porque this puede se帽ala a windows
<h4>Streams de escritura</h4>
process.stdout.write("hola")
process.stdout.write("que")
process.stdout.write("tal")
// OUTPUT: holaquetal
// stdout ya es un buffer de escritura
<h4>Streams de lectura y escritura (transformaci贸n)</h4>
const stream = requiere("stream")
const transform = string.tranform // esto crea un string de tranformaci贸n 
cont util = require("util")

function mayusculator () {
	transform.call(this)
}
util.inherts(mayusculato, transform);
mayusculator.prototye.transorm = function (chunk, codif, callback) {
	chunkmayusculator = chunk.toString().tuUpperCase();
	this.push(chunkmayusculator)
callback()
}
let mayus = new mayus ()
	stream.pipe(mayus)
				.pipe(process.stdout)

La verdad no end铆 la ultima, solo lo copiar茅 quiza no entienda ahora pero mas adelante cuando aprenda nuevos conceptos s铆, igualmente hay otros cursos con otros profesores que explican el mismo concepto, quiz谩 a ellos si le puedan entender no se romapn la cabeza 馃槂

No entend铆 el motivo de utilizar 'util.inherits', cuando se podr铆a usar simplemente Mayus.prototype = new Transform() ``` const fs = require('fs'), stream = require('stream') const const readable = fs.createReadStream(__dirname + '/texto.txt') const Transform = stream.Transform function Mayus(_this) { Transform.call(this) } Mayus.prototype = new Transform() Mayus.prototype._transform = function(chunk, codif, cb) { mayusChunk = chunk.toString().toUpperCase() this.push(mayusChunk) cb() } const mayus = new Mayus(this) readable.pipe(mayus).pipe(process.stdout) ```

Streams
Los streams son flujos de informaci贸n que usamos en la transmici贸n de datos binarios. El flujo de informaci贸n que forma un stream se transmite en pedazos, mejor conocidos como chunk. Los chunk no son m谩s que objetos de la clase Buffer

Esta clase es important铆sima. Se me ocurre que podemos desarrollar filtros para audio, video, overlays de caracteres para transmisiones en vivo, codecs y m谩s. Habr谩 que probar. Gracias!

Si quieren verlo en forma de clases en lugar de prototipos creo que se entiende mejor:

const fs = require('fs')
const {Transform} = require('stream')

let readableStream = fs.createReadStream(`${__dirname}/input.txt`)
readableStream.setEncoding('UTF8')

/*al colocar Tranform.call(this) estas iniciando el llamado a la tranformacion de tu secuencia datos. y al colocar this estas diciendo que se har谩 dentro de la clase (tomado de otro comentario)*/

class UpperCase extends Transform {
    constructor(){
        super()
        Transform.call(this)
    }

    _transform(chunk, encoding, cb) {
        let upperChunk = chunk.toString().toUpperCase()
        this.push(upperChunk)
        cb()
    }
}

//se crea la instancia de la clase
let upperCase = new UpperCase()

readableStream
    .pipe(upperCase)
    .pipe(process.stdout)

Una consulta, veo un curso de Fundamentos, luego un Curso de Node y luego un curso Pr谩ctico, dados por el gran Carlos. El orden ser铆a tal cual los he citado, 驴verdad?

Lo mismo tampoco estar铆a mal actualizarlos para ya usar clases y todo lo que trae ES6+

Un saludo y gracias.

PD: Gracias tambi茅n a los compa帽eros como siempre por compartir.

Que horrible clase, me imagino que el tema es complejo pero aun asi falto mucha explicaci贸n , parece una clase de magia porque todo apareci贸 de la nada

stdout: ya es un buffer de escritura

require(鈥榰til鈥): permite trabajar con herencia automatico

Creo que muchos entendemos que aqu铆 hubo herencia prototipal y dem谩s cosas, lo confuso aqu铆 son los m茅todos que se utilizaron, ya que seg煤n veo son propios de los m贸dulos que se est谩n requiriendo.

Considero que para entender mejor esta clase se tuvo que haber explicado al menos por encima los metodos que se usaron, tanto los de stream como los de util.

Es INCREIBLE lo bien que funciona el uncaughtException, tuve algunos errores en mi escritura de codigo, por lo tanto utilice este process con un console.error(err.message), 2 segundos mas tardes ya habia limpiado todo.
Sin lugar a dudas es increible la documentacion que nos prepara platzi para entender y mejorar!

Se puede pasar el codigo de la parte final a ECMAscript 2015 y quedaria asi.

const  { createReadStream } = require('fs')
const stream = require('stream')
let readableStream = createReadStream(__dirname + '/input.txt')

class Mayus extends stream.Transform {
    _transform(chunk, codif, cb) {
        let chunkMayus = chunk.toString().toUpperCase();
        this.push(chunkMayus);
        cb();
    }
}
let mayus = new Mayus();

readableStream
    .pipe(mayus)
    .pipe(process.stdout)

Wooow esta clase si me ha volado la cabeza, no la entend铆 馃槮

hace mucho que a una clase no le entendia jajajajaj

Para los que se confundieron:

B谩sicamente necesitamos crearnos una ++clase ++que herede el funcionamiento de Tranform

(para los que saben java este concepto est谩 m谩s f谩cil)

Por lo cual

podemos borrar:

function Mayus() {
    Transform.call(this);
}
util.inherits(Mayus, Transform);

cambiarlo por :

class Mayus extends Transform {
}

esto sugieren los IDE, donde hacen menci贸n a Ecmascript 6.

todo lo que eliminamos b谩sicamente era un truco para que Mayus herede el Transform ()

El codigo me da error.

const fs = require('fs');
const stream = require('stream');
const util = require ('util');

 let data = '';

 let readableStream = fs.createReadStream(__dirname + '/input.txt');
 readableStream.setEncoding('UTF8');

const Transform = stream.Transform;

function Mayusculas() {
    Transform.call(this);
}

util.inherits(Mayusculas, Transform);

Mayusculas.prototype._transform = (chunk, codif, callback) => {
    chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    callback();
}

let mayus = new Mayusculas();

readableStream
    .pipe(mayus)
    .pipe(process.stdout);

El mensaje de error que arroja es este:

$ node stream.js
C:\Users\fgarcia\Platzi\FundamentosNodeJS\memoria\stream.js:36
    this.push(chunkMayus);
         ^

TypeError: this.push is not a function
    at Mayusculas._transform (C:\Users\fgarcia\Platzi\FundamentosNodeJS\memoria\stream.js:36:10)
    at Mayusculas.Transform._read (_stream_transform.js:189:10)
    at Mayusculas.Transform._write (_stream_transform.js:177:12)
    at doWrite (_stream_writable.js:435:12)
    at writeOrBuffer (_stream_writable.js:419:5)
    at Mayusculas.Writable.write (_stream_writable.js:309:11)
    at ReadStream.ondata (_stream_readable.js:728:22)
    at ReadStream.emit (events.js:223:5)
    at addChunk (_stream_readable.js:309:12)
    at readableAddChunk (_stream_readable.js:286:13)

Lo que hace es literalmente leer input.txt, despu茅smodifica ese buffer la funci贸n Mayus y finalmente lo imprime al stdout.
.
Para pasar datos de un lado a otro de usa la funci贸n pipe() 馃榿
.
A煤n as铆 no me queda claro si todo esto se hace en un s贸lo stream, alguien podr铆a decirme si s铆 es un solo stream?

Este video puede ser confuso ya que en JavaScript no se manejan clases, es cierto que se usa

new Mayus()

Pero en realidad es Syntactic Sugar, al final, todo en JavaScript son Prototipos y me parece que hay un curso de JavaScript aqu铆 en Platzi en el cual explican mejor todos estos conceptos y como this se comporta diferente si se utilizan Arrow Functions.

el tranform llev谩ndolo a un contexto real me imagino que puede servir para cambiar la definici贸n de un v铆deo o no?

Algo no hice bien, pero no se donde!

me da este error!

nodemon] clean exit - waiting for changes before restart
[nodemon] restarting due to changes...
[nodemon] starting `node stream.js`
HOLA 
EVENTSOURCE
ES UN 
ARCHIVO 
        XMLDOCUMENT

        X_0
/Applications/XAMPP/xamppfiles/htdocs/platzi master/Fundamentos de nodeJS/memoria/stream.js:24
    this.push(chunkMayus);
         ^

TypeError: this.push is not a function
    at Mayus._transform (/Applications/XAMPP/xamppfiles/htdocs/platzi master/Fundamentos de nodeJS/memoria/stream.js:24:10)
    at Mayus.Transform._read (_stream_transform.js:189:10)
    at Mayus.Transform._write (_stream_transform.js:177:12)
    at doWrite (_stream_writable.js:431:12)
    at writeOrBuffer (_stream_writable.js:415:5)
    at Mayus.Writable.write (_stream_writable.js:305:11)
    at ReadStream.ondata (_stream_readable.js:726:22)
    at ReadStream.emit (events.js:210:5)
    at addChunk (_stream_readable.js:308:12)
    at readableAddChunk (_stream_readable.js:285:13)
[nodemon] app crashed - waiting for file changes before starting...```

No se si entienda un poquito mejor la utlima parte usando clases, aqu铆 dejo el c贸digo como lo entend铆.
Transform lo me que permite es alterar alterar los datos que pasan por el stream (flujo de datos). Como en este caso pasar a mayusculas el recurre al metodo _transform para operar con los datos, el cual lo definimos para darle la funcionalidad que nosotros deseamos.

class Mayus extends Transform{
    constructor(){
        super()
        Transform.call(this);
    }
    _transform(chunk,codif,cb){
        let chunkMayus = chunk.toString().toUpperCase();
        this.push(chunkMayus);
        cb();
    }
}

me esta dando error.

Este es mi codigo

const fs = require('fs');
const stream = require('stream');
const util = require ('util');

 let data = '';

 let readableStream = fs.createReadStream(__dirname + '/input.txt');
 readableStream.setEncoding('UTF8');




const Transform = stream.Transform;

function Mayusculas() {
    Transform.call(this);
}

util.inherits(Mayusculas, Transform);

Mayusculas.prototype._transform = (chunk, codif, callback) => {
    chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    callback();
}

let mayus = new Mayusculas();

readableStream
    .pipe(mayus)
    .pipe(process.stdout);


el error que me da es este:

$ node stream.js
C:\Users\fgarcia\Platzi\FundamentosNodeJS\memoria\stream.js:36
    this.push(chunkMayus);
         ^

TypeError: this.push is not a function
    at Mayusculas._transform (C:\Users\fgarcia\Platzi\FundamentosNodeJS\memoria\stream.js:36:10)
    at Mayusculas.Transform._read (_stream_transform.js:189:10)
    at Mayusculas.Transform._write (_stream_transform.js:177:12)
    at doWrite (_stream_writable.js:435:12)
    at writeOrBuffer (_stream_writable.js:419:5)
    at Mayusculas.Writable.write (_stream_writable.js:309:11)
    at ReadStream.ondata (_stream_readable.js:728:22)
    at ReadStream.emit (events.js:223:5)
    at addChunk (_stream_readable.js:309:12)
    at readableAddChunk (_stream_readable.js:286:13)

Es la primera clase de Carlos que no me qued贸 claro a la primeria. pero razon茅 que lo que estaba haciendo era crear una clase Mayus que extiende a Transform y que sobrecarga el m茅todo _transform.

aqu铆 mi versi贸n con alta az煤car sint谩ctica.

class Mayus extends stream.Transform{
    _transform(chunk, codif, cb){
        const chunkMayus = chunk.toString().toUpperCase();
        this.push(chunkMayus);
        cb();
    }
}

let mayusc = new Mayus();

readableStream.pipe(mayusc).pipe(process.stdout);

Para los que de pronto no entendieron bien el comportamiento de _transform o inherits, aqu铆 les dejo el mismo c贸digo escrito de otra manera para ver si lo pueden entender mejor!

const fs = require('fs');
const stream = require('stream');

let data = ''; 

let readeableStream = fs.createReadStream(`${__dirname}/practicas.js`);

readeableStream.setEncoding('UTF8');

readeableStream.on('data', datos => {
    data += datos; 
}) 

readeableStream.on('end', () => {
    console.log('Ya se termino!!!')
});

class Mayus extends stream.Transform { // Ingresa CTRL + Click en el stream.Transform para ver que en el constructor se ejecuta el m茅todo que estamos sobrescribiendo (VS Code)
    _transform(chunk) { // Y este es el m茅todo que apenas se ejecuta con el constructor
        let chunkMayus = chunk.toString().toUpperCase();
        console.log(this);
        this.push(chunkMayus);
        console.log(this);
    }
}
// El pipe b谩sicamente es un concepto que tambi茅n se ve en la consola que es pasarle informaci贸n de un comando a otro para que lo utilice de argumento, si no te quedo muy claro googlea 'Pipe operators' y de pronto vas a comprenderlo mejor
readeableStream 
    .pipe(new Mayus()) // Vas a ver que el pipe va a pasarle lo que ley贸 como opciones del constructor!
    .pipe(process.stdout)

Les comparto esto que puede resultar una gran herramienta a lo hora de tratar de entender este tipo de cosas que a veces los profes se salta.

Si mantienen presionado la tecla Ctrl. y posicionan su cursor sobre las clases, m茅todos, objetos y dem谩s en VSCode, te brinda m谩s informaci贸n sobre el mismo, por ejemplo su construcci贸n o instanciaci贸n e incluso se subraya y vuelve hiperv铆nculo que te lleva al C贸digo del mismo

Al hacer esto, sobre el 鈥榮tream鈥 de const Transform = stream.Transform; pude ver que stream es una clase y que Transform viene igual de otra clase.

Cuando hacer esto, y navegas por el C贸digo, encuentras lo siguiente que ayuda a entender mejor el Transform y el _transform.

Aqu铆 abajo el c贸digo de cada una por si les ayuda a entender mejor.

class Transform extends Duplex {
            constructor(opts?: TransformOptions);
            _transform(chunk: any, encoding: BufferEncoding, callback: TransformCallback): void;
            _flush(callback: TransformCallback): void;
        }

Con esto pude entender que no estamos nombrando cosas al aire sino m谩s bien invocando clases o prototipos del internal de Node.

Si aportar m谩s a esto, estar铆a de lujo ya que siento que si qued贸 poco claro.

Les dejo el c贸digo por si alguien se perdi贸 sobre el final como yo 馃榿

const fs = require("fs");
const stream = require("stream");
const util = require("util");

let data = "";

let readableStream = fs.createReadStream(__dirname + "/input.txt")

readableStream.setEncoding("utf-8");

// readableStream.on("data", function (chunk) {
// 	console.log(chunk);
// });

// readableStream.on("end", function() {
// 	console.log(data);
// });

// process.stdout.write("Hola");
// process.stdout.write("que");
// process.stdout.write("tal");

const Transform = stream.Transform;

function Mayus() {
	Transform.call(this);
}

util.inherits(Mayus, Transform);

Mayus.prototype._transform = function(chunk, codif, cb) {
	chunkMayus = chunk.toString().toUpperCase();
	this.push(chunkMayus);
	cb();
}

let mayus = new Mayus();

readableStream
	.pipe(mayus)
	.pipe(process.stdout) 
/* Streams es el paso de datos de un lado a otro */

const fs = require('fs');
const stream = require('stream');
const util = require('util');

let data = '';
/* 
Con esto empezamos a abrir los datos de un archivo */

let reasableStream = fs.createReadStream(__dirname + '/input.txt');

/* reasableStream.on('data', function (chunk) {
    console.log(chunk);
    console.log(chunk.toString());
}) */
/* Esta es una forma de pasar la informacion de hexa a formato UFT8 */
reasableStream.setEncoding('UTF8');

/* Si tenemos un archivo muy pero muy grande podemos enviar toda la informacion a que se procese primero y cuando este todo listo mostralo, se hace asi: */

/* reasableStream.on('data', function (chunk) {
   data += chunk;
})

reasableStream.on('end', function () {
    console.log(data);
    console.log('Soy yo');
 }) */

/* la diferencia de hacer esto se nota en memoria y para cosas grandes como suvir  un archivo de 20GB  a internet */

/* Esto es un steam de escritura */

/* process.stdout.write('Hola')
process.stdout.write('que')
process.stdout.write('tal') */


/* Esto es un buffer de lectura y escritura lee del fichero pasa a mayuscula y escribe */

const Transform = stream.Transform;

function Mayus() {
    Transform.call(this);
}
util.inherits(Mayus, Transform);

Mayus.prototype._transform = function(chunk, codif, cb) {
    chunkMayus = chunk.toString().toUpperCase();
    this.push(chunkMayus);
    cb();
}

let mayus = new Mayus();

reasableStream
    .pipe(mayus)
    .pipe(process.stdout);

Un chunk es un conjunto de buffers? O es lo mismo?

que es chunk?

Aqui esta la documentacion de node sobre Transform y algunas alternativas de como es posible escribirlos https://nodejs.org/docs/latest/api/stream.html#stream_implementing_a_transform_stream

Intente hacer el ejecicio con ARROW FUNCTIONS:

 () => {}

No pude por que marcaba error. Que raro.

Aqu铆 les dejo una lectura sobre los Streams en NodeJS

En 2023 (node 20), el c贸digo ser铆a: *const* *Transform* = *stream*.*Transform*; *const* mayus = new *Transform*({聽 聽 transform(*chunk*,*encodig*,*callback*){聽 聽 聽 聽 this.push(*chunk*.toString().toUpperCase())聽 聽 聽 聽 callback()聽 聽 }}) readbleStream.pipe(mayus).pipe(process.stdout);

Ya llevo como 3 a帽os programando con node. Entendi lo que hizo el profe con los pipes y creando una 鈥淐lase鈥 que hereda de Transform. Pero igual siento que toda la explicacion fue muy apresurada y no se entendio muy bien que hace Transform en si.

Hola aqui una modificacion del codigo porque util.inherits ya esta deprecado

const fs = require('fs');
const stream = require('stream');

let readableStream = fs.createReadStream(__dirname + '/readme.md');
readableStream.setEncoding('UTF8');
readableStream.on('data', function (chunk) {
    console.log(chunk);
    // console.log(chunk.toString()); // ya no es necesario si se modifica el Encoding
});


class Upper extends stream.Transform {

    _transform(chunk, encoding, callback) {
        this.chunkUpper = chunk.toString().toUpperCase();
        this.push(this.chunkUpper);
        callback();
    }
}

let upper = new Upper();
readableStream.pipe(upper)
    .pipe(process.stdout)

Este es un ejemplo de stream de escritura

const fs = require('fs');

// Creamos un Stream de escritura
const writeStream = fs.createWriteStream('output.txt');

// Escribimos en el Stream de escritura
writeStream.write('Hola, ');
writeStream.write('Mundo!');
writeStream.write('\n');

// Cerramos el Stream de escritura
writeStream.end();

console.log('Archivo creado exitosamente!');

Este c贸digo no funciona.

Otra forma de transformar el chunk es rest谩ndole 32 (al chunk), porque a es 97 en binario y A es 65 en binario

//  Streams

//  Se utiliza para captar la informacion recibida en partes "Principalmente usada para
//  grandes cantidades". Y modificarla dependiendo del uso

//fs ya marcado antes con require
const stream = require('stream');
const util = require('util')
//  b谩sicamente lo que hace es transformar la secuencia de entrada para que la secuencia de salida sea una diferente
const Transform = stream.Transform;

let data = '';

let readableStream = fs.createReadStream(__dirname + '/input.txt')
readableStream.setEncoding('utf8')


// readableStream.on('data', function (chunk) {
//     data += chunk;
// })

// readableStream.on('end', function(){
//     console.log(data);
// })

// process.stdout.write('abc')

// esta funci贸n ser谩 donde ejecutaras la transformaci贸n. al colocar Tranform.call(this) estas iniciando el llamado
//  a la tranformacion de tu secuencia datos. y al colocar this estas diciendo que se har谩 dentro del m茅todo Mayus
// function Mayus(){
//     Transform.call(this);
// }
// // es crear una instancia de la clase Transform y estableci茅ndolo como prototipo a la funci贸n Mayus.
// util.inherits(Mayus, Transform);

// // Se podra ver que cambio o que transformaci贸n le har谩s a la secuencia de datos que estas recibiendo como entrada.
// Mayus.prototype._transform = function(chunk, codif, cb){
//     chunkMayus = chunk.toString().toUpperCase()
//     this.push(chunkMayus);
//     cb();
// }

// La version nueva utilizando constructor.

class Mayus extends Transform {
      constructor() {
            super();
            Transform.call(this);
      }
      _transform = (chunk, codif, cb) => {
            let chunkMayus = chunk.toString().toUpperCase();
            this.push(chunkMayus);
            cb();
      };
}


// creas una instancia de la funcion Mayus
let mayus = new Mayus();

// es limitar el almacenamiento en el buffer para que no haya una sobresaturacion a la hora se pasar la secuencia de los datos
readableStream
    .pipe(mayus)
    .pipe(process.stdout)
Mala la clase

Me explot贸 la cafetera con esta clase jajaja

La clase fue muy didactica

Esta tema no es sencillo. Podr铆a dar para un curso entero.

Alguien sabe que sig que algo empiece con mayuculas? Por ejemplo Transform

La verdad de esta clase solo entend铆 hasta que hizo la modificaci贸n de ah铆 para adelante se fue enredando como un callback hell xD

quien seria this en este caso??

Podr铆a decirse que un Stream es el proceso de ir consumiendo datos al tiempo en que se reciben

Me perd铆 y hasta me saco error jajajajaja 铆bamos bien pero aqu铆 varios conceptos estuvieron bastantes complejos.

Me surge la duda, 驴se podr铆a utilizar class de ES6 para este caso?

Estar铆a muy bueno que a帽adan un video luego de este donde se nos proporcione en archivos un file extensivo y mandarlo a una variable en chunks para notar esa diferencia.

En qu茅 caso usar streams

Streams pasar algo de un lugar a otro

A mi me imprime directo en UTF-8 sin que lo especifique o lo cambie a string 馃槷 Alguien sabe pq? Tal vez nueva versi贸n

馃挜

Desde el minuto 08:10 no entend铆 lo que pasaba, jajaj

Entend铆 poco la 煤ltima parte 馃槮

Ahora s茅 por qu茅 mientras mis podcasts cargan dicen: Almacenando en b煤fer. Ah铆 me viene una pregunta: 驴C贸mo se trata 茅sto con archivos de audio y video?