JavaScript File e FileReader
No desenvolvimento web moderno, lidar com arquivos de forma eficiente e segura é essencial. O JavaScript oferece interfaces robustas para isso.
Aplicações web frequentemente precisam trabalhar com arquivos selecionados pelo usuário: ler um documento de texto, pré-visualizar uma imagem antes do upload ou processar dados binários no navegador. O JavaScript lida com isso por meio de duas interfaces relacionadas. A interface File descreve um único arquivo (seu nome, tamanho e tipo), e a interface FileReader lê o conteúdo desse arquivo de forma assíncrona, sem jamais enviá-lo a um servidor.
Este guia explica como obter um File de um <input>, lê-lo com FileReader e usar os métodos mais modernos baseados em promessas file.text() e file.arrayBuffer(). Um File é um tipo especializado de Blob, portanto a maior parte do que você aprender aqui também se aplica a blobs; consulte a visão geral mais ampla da File API para o panorama completo.
Entendendo a Interface File em JavaScript
A interface File representa os dados de um único arquivo. Os arquivos geralmente vêm de um elemento <input type="file">, de uma operação de arrastar e soltar ou da Clipboard API. Como um File estende Blob, ele carrega o conteúdo do arquivo mais metadados sobre ele.
Principais Propriedades da Interface File
name: O nome do arquivo como uma string, por exemplo"relatorio.pdf".size: O tamanho do arquivo em bytes (um número).type: O tipo MIME como uma string, por exemplo"image/png". Pode ser""se o navegador não conseguir determiná-lo.lastModified: Um timestamp (milissegundos desde a época Unix) de quando o arquivo foi alterado pela última vez.
Obtendo arquivos de um input
Um <input> de arquivo expõe uma propriedade files — um FileList, que é semelhante a um array. Use event.target.files[0] para o primeiro arquivo, ou defina o atributo multiple e itere sobre files para lidar com vários arquivos de uma vez.
Exemplo: Exibindo Informações do Arquivo
Aqui está uma forma simples de exibir informações sobre um arquivo que o usuário seleciona:
<input type="file" id="fileInput" />
<div id="fileInfo"></div>document.getElementById('fileInput').addEventListener('change', function(event) {
const file = event.target.files[0];
if (!file) return; // user cancelled the dialog
const modified = new Date(file.lastModified).toLocaleString();
const info = `File Name: ${file.name}<br>
File Size: ${file.size} bytes<br>
File Type: ${file.type || 'unknown'}<br>
Last Modified: ${modified}`;
document.getElementById('fileInfo').innerHTML = info;
});Utilizando a FileReader API
A interface FileReader lê o conteúdo de um File ou Blob de forma assíncrona. Você inicia uma leitura com um dos seus métodos readAs… e, em seguida, trata o resultado por meio de eventos — os dados reais nunca bloqueiam a thread principal.
Métodos do FileReader
readAsText(file): Lê o arquivo como uma string de texto (opcionalmente com uma codificação específica).readAsDataURL(file): Lê o arquivo como uma URL de dados codificada em base64 — útil para pré-visualizações em<img src>.readAsArrayBuffer(file): Lê o arquivo como umArrayBufferde bytes brutos para processamento binário.
Eventos do FileReader
Como a leitura é assíncrona, você deve anexar os handlers antes de chamar um método readAs…:
onload: Dispara quando a leitura é concluída com sucesso; os dados estão emreader.result(também disponível comoevent.target.result).onerror: Dispara se a leitura falhar; inspecionereader.error.onprogress: Dispara periodicamente durante a leitura;event.loadedeevent.totalpermitem exibir uma barra de progresso para arquivos grandes.
Exemplo: Lendo um Arquivo de Texto
O exemplo a seguir lê um arquivo de texto com FileReader e exibe seu conteúdo, incluindo a porcentagem de progresso:
<input type="file" id="textInput" />
<div id="textOutput">Upload a text file please</div>document.getElementById('textInput').addEventListener('change', function(event) {
const file = event.target.files[0];
if (!file) return;
const output = document.getElementById('textOutput');
const reader = new FileReader();
reader.onprogress = function(e) {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
output.textContent = `Reading… ${percent}%`;
}
};
reader.onload = function(e) {
output.textContent = e.target.result;
};
reader.onerror = function() {
output.textContent = 'Error reading file: ' + reader.error;
};
reader.readAsText(file);
});Leitura Avançada de Arquivos: Lidando com Diferentes Tipos de Dados
Lendo Imagens como Data URLs
Para exibir um arquivo de imagem selecionado pelo usuário, você pode lê-lo como uma Data URL usando o método readAsDataURL. Esse método codifica o arquivo como uma string em base64, que pode ser usada diretamente em elementos de imagem.
Exemplo: Exibindo uma Imagem
<input type="file" id="imageInput" />
<div>Select an image file, please.</div>
<img id="imageDisplay" />document.getElementById('imageInput').addEventListener('change', function(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('imageDisplay').src = e.target.result;
};
reader.onerror = function() {
document.getElementById('imageDisplay').style.display = 'none';
alert('Error reading image file.');
};
reader.readAsDataURL(file);
});Lendo Arquivos Binários com ArrayBuffer
Para aplicações que precisam processar áudio, vídeo ou qualquer dado binário, ler o arquivo como um ArrayBuffer é essencial. Esse método fornece um buffer genérico de dados binários, que pode ser manipulado ou passado para outras APIs como Web Audio ou WebGL.
Exemplo: Processando Dados Binários
<input type="file" id="binaryInput" />
<div id="binaryOutput">Select any file.</div>document.getElementById('binaryInput').addEventListener('change', function(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = function(e) {
const buffer = e.target.result;
// Process the binary data
const info = `Buffer Length: ${buffer.byteLength} bytes`;
document.getElementById('binaryOutput').innerHTML = info;
};
reader.onerror = function() {
document.getElementById('binaryOutput').innerHTML = 'Error reading binary file.';
};
reader.readAsArrayBuffer(file);
});A Forma Moderna: file.text() e file.arrayBuffer()
O FileReader é anterior às promessas, então sua API baseada em eventos pode parecer verbosa. Todos os navegadores modernos adicionam métodos que retornam promessas diretamente em File/Blob, permitindo que você leia com async/await:
file.text(): Resolve para o conteúdo do arquivo como uma string UTF-8.file.arrayBuffer(): Resolve para umArrayBufferdos bytes brutos.file.stream(): Retorna umReadableStreampara processar arquivos muito grandes em partes.
<input type="file" id="modernInput" />document.getElementById('modernInput').addEventListener('change', async function(event) {
const file = event.target.files[0];
if (!file) return;
try {
const text = await file.text();
console.log('First 100 characters:', text.slice(0, 100));
const buffer = await file.arrayBuffer();
const bytes = new Uint8Array(buffer);
console.log('Total bytes:', bytes.length);
console.log('First byte:', bytes[0]);
} catch (err) {
console.error('Could not read file:', err);
}
});Prefira esses métodos baseados em promessas para código novo — eles se integram de forma limpa com async/await e try/catch. Use o FileReader quando precisar de eventos onprogress ou precisar dar suporte a navegadores muito antigos. Para enviar arquivos a um servidor em partes retomáveis, combine file.slice() com essas leituras — veja upload de arquivo retomável.
Conclusão
A interface File informa sobre um arquivo (nome, tamanho, tipo, lastModified), enquanto o FileReader e os métodos modernos file.text() / file.arrayBuffer() permitem ler seu conteúdo sem uma viagem de ida e volta ao servidor. Juntos, eles cobrem as necessidades mais comuns: exibir metadados do arquivo, pré-visualizar imagens, analisar texto e processar dados binários inteiramente no navegador.
Para ir além, explore o tipo relacionado Blob no qual File se baseia e a visão geral mais ampla da File API.