Back

Trabalhando com Arquivos Usando a API FileReader

Trabalhando com Arquivos Usando a API FileReader

Quando um usuário seleciona um arquivo em sua aplicação web, você obtém um objeto File — mas como você realmente lê seu conteúdo? É aí que entra a API FileReader do JavaScript. Este artigo explica como o FileReader funciona, quando usá-lo e como ele se compara às alternativas modernas.

Principais Conclusões

  • A API FileReader lê o conteúdo de File ou Blob de forma assíncrona usando um dos três métodos: readAsText(), readAsArrayBuffer() ou readAsDataURL().
  • O FileReader usa um modelo orientado a eventos com eventos load, error, progress e outros para comunicar resultados.
  • Você pode encapsular o FileReader em uma Promise para uma integração mais limpa com código async/await.
  • Os métodos modernos Blob.text() e Blob.arrayBuffer() são mais simples para leituras básicas, mas o FileReader ainda é a escolha certa quando você precisa de rastreamento de progresso, codificação não-UTF-8 ou URLs de dados base64.

O Que É a API FileReader?

A API FileReader é uma interface do navegador que lê o conteúdo de objetos File ou Blob de forma assíncrona. Ela não pode acessar arquivos arbitrários no sistema do usuário por caminho — funciona apenas com arquivos que o usuário selecionou explicitamente, seja através de <input type="file"> ou de uma interação de arrastar e soltar.

const input = document.querySelector('input[type="file"]')

input.addEventListener('change', () => {
  const file = input.files[0]
  console.log(file.name, file.size, file.type)
})

Um objeto File herda de Blob, então ele carrega as mesmas propriedades mais name e lastModified. Você o passa diretamente para qualquer método de leitura do FileReader.

Os Três Métodos Principais de Leitura

Ler arquivos locais em JavaScript com FileReader significa escolher o formato de saída correto:

  • readAsText(file, encoding?) — Retorna o conteúdo do arquivo como uma string. Padrão UTF-8. Útil para CSV, JSON, texto simples ou qualquer formato baseado em texto.
  • readAsArrayBuffer(file) — Retorna dados binários brutos como um ArrayBuffer. Use isso para imagens, áudio, PDFs ou qualquer processamento binário.
  • readAsDataURL(file) — Retorna uma URL data: codificada em base64. Conveniente para pré-visualizações de imagens, mas observe que o resultado é aproximadamente 33% maior que o arquivo original devido à sobrecarga de codificação base64.

Evite readAsBinaryString() — está obsoleto. Use readAsArrayBuffer() em vez disso para dados binários.

O Modelo Orientado a Eventos do FileReader

O FileReader é assíncrono e se comunica através de eventos. Os principais são:

EventoQuando dispara
loadstartA leitura começa
progressDispara periodicamente durante a leitura
loadLeitura concluída com sucesso
errorLeitura falhou
loadendLeitura finalizada (sucesso ou falha)

Aqui está uma pré-visualização prática de imagem antes do upload usando readAsDataURL():

function previewImage(file) {
  const reader = new FileReader()

  reader.addEventListener('load', () => {
    const img = document.querySelector('#preview')
    img.src = reader.result
  })

  reader.addEventListener('error', () => {
    console.error('Failed to read file:', reader.error)
  })

  reader.readAsDataURL(file)
}

O evento progress é particularmente útil para mostrar uma barra de progresso com arquivos grandes:

reader.addEventListener('progress', (event) => {
  if (event.lengthComputable) {
    const percent = Math.round((event.loaded / event.total) * 100)
    progressBar.value = percent
  }
})

Encapsulando o FileReader em uma Promise

O estilo de callback do FileReader pode parecer desajeitado em código assíncrono moderno. Um wrapper simples resolve isso:

function readFileAsText(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.addEventListener('load', () => resolve(reader.result))
    reader.addEventListener('error', () => reject(reader.error))
    reader.readAsText(file)
  })
}

// Uso
const text = await readFileAsText(file)

FileReader vs Blob.text() e Blob.arrayBuffer()

Navegadores modernos suportam métodos baseados em promises diretamente no Blob (e, portanto, em File):

// Abordagem moderna — mais simples para leituras básicas
const text = await file.text()
const buffer = await file.arrayBuffer()

Então, quando você ainda deve usar o FileReader? Escolha-o quando precisar de:

  • Rastreamento de progresso via evento progress (embora para arquivos locais alguns navegadores possam disparar apenas um pequeno número de eventos de progresso)
  • Suporte a codificação não-UTF-8 via readAsText(file, 'ISO-8859-1')
  • URLs de dados base64 via readAsDataURL()
  • Suporte mais amplo a navegadores legados

Para leituras diretas de texto ou binário em aplicações modernas, Blob.text() e Blob.arrayBuffer() são mais limpos. Para pré-visualizações de imagens, URL.createObjectURL(file) evita a expansão base64 e geralmente é mais eficiente em termos de memória do que readAsDataURL(). Apenas lembre-se de chamar URL.revokeObjectURL() quando a URL do objeto não for mais necessária para evitar vazamentos de memória.

Conclusão

A API FileReader permanece uma ferramenta prática para trabalhar com objetos File no navegador — especialmente quando você precisa de eventos de progresso, controle de codificação ou URLs de dados. Para casos mais simples, os métodos Blob mais recentes requerem menos código. Conheça ambos, e você lidará com qualquer cenário de leitura de arquivos de forma limpa.

Perguntas Frequentes

Não. O FileReader só pode ler arquivos que o usuário selecionou explicitamente através de um elemento input ou interação de arrastar e soltar. O modelo de segurança do navegador impede que o JavaScript acesse arquivos arbitrários no sistema de arquivos por caminho. Esta restrição existe para proteger a privacidade do usuário e a segurança do sistema.

readAsArrayBuffer retorna dados binários brutos adequados para processamento ou manipulação, como análise de metadados de imagem ou formas de onda de áudio. readAsDataURL retorna uma string codificada em base64 que você pode usar diretamente como src de imagem ou background CSS. A abordagem de URL de dados é conveniente, mas produz uma saída aproximadamente 33 por cento maior que o arquivo original.

Se você só precisa do conteúdo de texto e sua aplicação tem como alvo navegadores modernos, Blob.text() é mais simples porque retorna uma Promise diretamente. Use FileReader quando precisar de rastreamento de progresso para arquivos grandes, precisar especificar uma codificação não-UTF-8 ou precisar suportar navegadores mais antigos que não possuem o método Blob.text().

Se você usar URL.createObjectURL para gerar uma URL de pré-visualização, chame URL.revokeObjectURL assim que a imagem for carregada ou a pré-visualização for removida. Se você usar readAsDataURL em vez disso, a string base64 é gerenciada automaticamente pela coleta de lixo, mas consome mais memória do que uma URL de objeto para o mesmo arquivo.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay