Streams no Node


Streams são uma das características mais importantes do Node, permitindo manipular dados de forma eficiente, especialmente quando se lida com grandes volumes de dados.

Existem dois tipos principais de streams: Readable e Writable.

  • Readable Streams: São streams de onde os dados podem ser lidos. Exemplos incluem leitura de arquivos, solicitações HTTP, ou qualquer outra fonte de dados. Os dados são consumidos através de eventos de ‘data’, enquanto o fim da transmissão é sinalizado pelo evento ‘end’.

  • Writable Streams: São streams onde os dados podem ser escritos. Exemplos incluem gravação em arquivos, respostas HTTP, ou qualquer outra saída de dados. Os dados são escritos através do método ‘write’, e o final da escrita é sinalizado pelo método ‘end’.

Suponha que sua aplicação precise receber o envio de um arquivo .csv de 1GB para o servidor Node, para isso vamos considerar duas abordagens: uma enviando o arquivo inteiro de uma vez e a outra utilizando streams.

Enviando o arquivo inteiro de uma vez

import http from 'http';
import fs from 'fs';
 
const server = http.createServer((req, res) => {
  fs.readFile('arquivo.csv', (err, data) => {
    if (err) {
      res.writeHead(500);
      return res.end(err.message);
    }
    res.writeHead(200, { 'Content-Type': 'text/csv' });
    res.end(data);
  });
});
 
server.listen(3000, () => {
  console.log('Servidor escutando na porta 3000');
});

Neste exemplo, o arquivo é carregado inteiramente na memória usando readFile e enviado como uma única resposta HTTP. Isso pode ser problemático para arquivos grandes, pois consome muita memória, especialmente se houver muitas solicitações simultâneas.

Usando Streams:

import http from 'http';
import fs from 'fs';
 
const server = http.createServer((req, res) => {
  const fileStream = fs.createReadStream('arquivo.csv');
  fileStream.pipe(res);
});
 
server.listen(3000, () => {
  console.log('Servidor escutando na porta 3000');
});

Neste exemplo, o arquivo é lido e enviado ao servidor através de uma Readable Stream. Isso significa que o arquivo não é carregado inteiramente na memória, mas sim lido e enviado em pedaços, tornando-o mais eficiente em termos de consumo de memória, especialmente para arquivos grandes.

Note

Em resumo, o uso de streams é preferível ao lidar com grandes volumes de dados, pois permite processar os dados de forma eficiente, evitando gargalos de memória. O Node.js é otimizado para trabalhar com streams, e sua utilização pode melhorar significativamente o desempenho de aplicações que lidam com grandes volumes de dados.

Referências