Download Eficiente de Arquivos Grandes no Node.js com Fetch e Streams

Download Eficiente de Arquivos Grandes no Node.js com Fetch e Streams

Fazer download de arquivos volumosos carregando todo o conteúdo na memória RAM antes de salvar no disco pode travar a aplicação e causar estouro de memória (out of memory). O uso da API nativa fetch combinada com ReadableStream do Node.js e fs.createWriteStream resolve esse gargalo ao transferir o arquivo em fluxo contínuo diretamente para o sistema de arquivos.

JavaScript

const fs = require('fs');
const { pipeline } = require('stream/promises');

/**
 * Realiza o download de um arquivo via stream e o salva diretamente no disco.
 * @param {string} url - URL do arquivo a ser baixado.
 * @param {string} caminhoDestino - Caminho local onde o arquivo será salvo.
 */
async function baixarArquivoComStream(url, caminhoDestino) {
  const resposta = await fetch(url);

  // Valida se a requisição HTTP foi bem-sucedida
  if (!resposta.ok) {
    throw new Error(`Falha ao baixar arquivo: ${resposta.status} ${resposta.statusText}`);
  }

  // Obtém a stream de leitura do corpo da resposta e cria a stream de escrita no disco
  const streamLeitura = resposta.body;
  const streamEscrita = fs.createWriteStream(caminhoDestino);

  // Conecta a stream de entrada diretamente ao arquivo de destino
  await pipeline(streamLeitura, streamEscrita);
  console.log(`[Sucesso] Download concluído e salvo em: ${caminhoDestino}`);
}

// --- Exemplo Prático de Uso ---
(async () => {
  const urlExemplo = 'https://httpbin.org/bytes/102400'; // Gera um arquivo de teste de ~100KB
  const destino = './arquivo_baixado.bin';

  try {
    console.log('Iniciando o download do arquivo...');
    await baixarArquivoComStream(urlExemplo, destino);
  } catch (erro) {
    console.error('Erro durante o download:', erro.message);
  }
})();

Pontos-chave

  • Consumo Baixo e Constante de RAM: A transferência ocorre em chunks (pequenos blocos de dados), garantindo uso mínimo de memória mesmo ao baixar arquivos de múltiplos gigabytes.
  • Uso da API fetch Nativa: A solução utiliza a API fetch integrada a partir do Node.js v18+, eliminando a necessidade de dependências externas como axios ou got.
  • Gerenciamento de Recursos com pipeline: A função stream/promises.pipeline garante o fechamento automático de todas as streams e a remoção de descritores de arquivo abertos caso ocorra uma falha na rede.
  • Tratamento do Corpo da Resposta: A propriedade resposta.body retorna uma instância compatível com ReadableStream, pronta para ser consumida e encadeada em streams graváveis do Node.js.

Thales de Oliveira Gomes

Thales de Oliveira Gomes é gestor de Tecnologia da Informação, especialista em infraestrutura de redes, computação em nuvem e operações de TI hospitalar, com mais de 18 anos de experiência na área. Graduado em Gestão de TI e pós-graduado em Engenharia de Redes e Telecomunicações, Cloud Computing, Redes de Computadores e Gestão Hospitalar, construiu uma trajetória sólida liderando projetos de alta complexidade, como a implementação e migração para nuvem de sistemas ERP de grande porte. Sua atuação no setor o levou a ser indicado ao prêmio IT Leaders Brasil na categoria Rising Leaders. Além da carreira corporativa e da paixão por tecnologia, Thales é autor independente com mais de 70 obras publicadas sobre redes, segurança da informação, Linux e física, além de criador de conteúdo no blog Vetor Tech e na plataforma CiberDicas. No universo das artes e do entretenimento, atua como produtor de música eletrônica sob o projeto Yknex, cria ilustrações digitais e compartilha walkthroughs de games no YouTube.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *