A Few About: Streams NodeJs (PT-BR)
Tags: node, learning, programming, streams
Published: 2023-09-27 19:38:28

**Streams** o conceito utilizado por Youtube, Netflix, Spotify entre outros para receber e enviar porções de dados grandes de/para usuários.

Uma ideia incompreendida e de difícil aplicabilidade. Mas, ao compreender, como tudo, é possível ver que não é nenhum “bicho de 7 cabeças”

No NodeJS é possível utilizar Streams, aliás foi a plataforma que veio para auxiliar os desenvolvedores a trabalhar com esse conceito, já que antigamente muitas ferramentas não trabalhavam e as que trabalhavam tinha um complexidade ainda maior.

### Mas o que são Streams?

É uma coleção de dados, assim como arrays e strings. A diferença entre arrays e strings é que esses dados não pode ser disponibilizados todos de uma vez e não precisam ficar todos alocados na memória de uma só vez, o que traz a possibilidade de poder trabalhar com grandes coleções de dados, seja de fonte interna ou externa.

Há dois conjuntos de Streams:

- Streams de Leitura (Requisição de dados ao servidor);
- Streams de Escrita (Envio de dados ao cliente);
- Streams Duplex (Leitura e Escrita ao mesmo tempo)

No NodeJS **Stream** é uma biblioteca nativa, onde possui objetos nativos para podermos trabalhar. Objetos como TCP Sockets, zlib e crypto streams.

Assim como na biblioteca padrão HTTP tem stdio (stdin, stdout, stderr), também tem na biblioteca Stream.

### Resumindo a funcionalidade…

Em resumo o Stream vai pegar um arquivo grande (Ex.: 2GB) e vai enviar/receber ele em partes, em torno de 25mb cada parte e no final vai reconstruir ele através de referencias para o elemento corrente, criadas antes de ser particionado. 

É uma forma de encapsular esta referência de forma que haja a possibilidade de percorrer todos os elementos da coleção de dados.

### Um exemplo prático

Criando um grande arquivo de String:

```jsx
const fs = require(’fs’);

const file = fs.createWriteStream(’./bigFile.txt’);

for (let i = 0; i ≤ 1e6; i++) {

file.write('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n');

}

file.end();
```

Foi utilizado para gravar um Stream de escrita. Onde foi gravado 1 milhão de linhas (1e6) com um loop `for` .

O módulo `fs` pode ser utilizado para ler e gravar arquivos usando uma interface de Stream. 

Se criarmos um servidor padrão para consumir esse arquivo, o consumo de memória vai elevar consideravelmente. Podemos testar da seguinte forma:

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

server.on('request', (req, res) => {
	fs.readFile('./bigFile.txt', (err, data) => {
	if (err) throw err;

	res.end(data);
	});
});

server.listen(8000);
```

Quando executar o código e fazer uma requisição solicitando o arquivo, será enviado, utilizando um método assíncrono `fs.readFile` .

Porém ao fazer essa solicitação, como disse anteriormente, o consumo de memória vai elevar significativamente.

Agora vamos codar a mesma coisa porém utilizando o método `createReadStream` do módulo `fs` .

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

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

server.listen(8000);
```

Agora ao executar verá que o consumo de memória será baixo, pois como explicado anteriormente, o arquivo foi fragmento em partes.

**Atualização**: Disponível em meu Github um repositório onde trabalho um pouco com Stream e HTTP no Nodejs. https://github.com/yestorootkit/Streams-Nodejs

Bom, espero ter conseguido explicar um pouco sobre Stream e mostrar um pouco do funcionamento dele no NodeJS.

Agradeço a leitura!