JavaScript File e FileReader
Nella moderna web app, gestire i file in modo efficiente e sicuro è fondamentale. JavaScript offre le interfacce File e FileReader per farlo.
Le applicazioni web hanno spesso bisogno di lavorare con i file selezionati dall'utente: leggere un documento di testo, visualizzare in anteprima un'immagine prima del caricamento, o elaborare dati binari nel browser. JavaScript gestisce tutto ciò con due interfacce correlate. L'interfaccia File descrive un singolo file (nome, dimensione e tipo), mentre l'interfaccia FileReader legge il contenuto di quel file in modo asincrono senza mai inviarlo a un server.
Questa guida spiega come ottenere un File da un <input>, leggerlo con FileReader e usare i metodi più moderni basati su promise file.text() e file.arrayBuffer(). Un File è un tipo specializzato di Blob, quindi la maggior parte di ciò che impari qui si applica anche ai blob; consulta la panoramica generale della File API per il quadro completo.
Comprendere l'interfaccia File in JavaScript
L'interfaccia File rappresenta i dati di un singolo file. I file provengono solitamente da un elemento <input type="file">, da un'operazione di trascinamento (drag-and-drop) o dalla Clipboard API. Poiché File estende Blob, contiene sia il contenuto del file che i metadati associati.
Proprietà principali dell'interfaccia File
name: Il nome del file come string, ad es."report.pdf".size: La dimensione del file in byte (un numero).type: Il tipo MIME come string, ad es."image/png". Può essere""se il browser non riesce a determinarlo.lastModified: Un timestamp (millisecondi dall'epoca Unix) che indica quando il file è stato modificato per l'ultima volta.
Ottenere file da un input
Un <input> di tipo file espone una proprietà files — un FileList, simile a un array. Usa event.target.files[0] per il primo file, oppure imposta l'attributo multiple e scorri i files per gestirne più di uno alla volta.
Esempio: visualizzare le informazioni di un file
Ecco un modo semplice per visualizzare le informazioni su un file selezionato dall'utente:
<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;
});Utilizzo della FileReader API
L'interfaccia FileReader legge il contenuto di un File o Blob in modo asincrono. Si avvia una lettura con uno dei suoi metodi readAs…, poi si gestisce il risultato tramite eventi — i dati effettivi non bloccano mai il thread principale.
Metodi di FileReader
readAsText(file): Legge il file come string di testo (opzionalmente con una codifica specificata).readAsDataURL(file): Legge il file come data URL codificata in base64 — comoda per le anteprime<img src>.readAsArrayBuffer(file): Legge il file comeArrayBufferdi byte grezzi per l'elaborazione binaria.
Eventi di FileReader
Poiché la lettura è asincrona, è necessario collegare i gestori prima di chiamare un metodo readAs…:
onload: Si attiva quando la lettura è completata con successo; i dati si trovano inreader.result(disponibile anche comeevent.target.result).onerror: Si attiva se la lettura fallisce; ispezionareader.error.onprogress: Si attiva periodicamente durante la lettura;event.loadedeevent.totalconsentono di mostrare una barra di avanzamento per file di grandi dimensioni.
Esempio: leggere un file di testo
Il seguente esempio legge un file di testo con FileReader e ne visualizza il contenuto, inclusa la percentuale di avanzamento:
<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);
});Lettura avanzata di file: gestione di diversi tipi di dati
Leggere immagini come Data URL
Per visualizzare un file immagine selezionato dall'utente, è possibile leggerlo come Data URL usando il metodo readAsDataURL. Questo metodo codifica il file come string in base64, che può essere usata direttamente negli elementi immagine.
Esempio: visualizzare un'immagine
<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);
});Leggere file binari con ArrayBuffer
Per le applicazioni che devono elaborare audio, video o qualsiasi dato binario, leggere il file come ArrayBuffer è essenziale. Questo metodo fornisce un buffer generico di dati binari che può essere manipolato o passato ad altre API come Web Audio o WebGL.
Esempio: elaborare dati binari
<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);
});Il metodo moderno: file.text() e file.arrayBuffer()
FileReader è precedente alle promise, quindi la sua API basata su eventi può risultare verbosa. Tutti i browser moderni aggiungono metodi che restituiscono promise direttamente su File/Blob, consentendo di leggere con async/await:
file.text(): Restituisce una promise con il contenuto del file come string UTF-8.file.arrayBuffer(): Restituisce una promise con unArrayBufferdei byte grezzi.file.stream(): Restituisce unReadableStreamper elaborare file molto grandi a blocchi.
<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);
}
});Preferisci questi metodi basati su promise per il nuovo codice — si integrano perfettamente con async/await e try/catch. Ricorri a FileReader quando hai bisogno degli eventi onprogress o devi supportare browser molto datati. Per inviare file a un server in blocchi ripristinabili, combina file.slice() con queste letture — consulta resumable file upload.
Conclusione
L'interfaccia File fornisce informazioni su un file (name, size, type, lastModified), mentre FileReader e i più recenti metodi promise file.text() / file.arrayBuffer() consentono di leggerne il contenuto senza round-trip al server. Insieme coprono le esigenze comuni: visualizzare i metadati del file, mostrare anteprime di immagini, analizzare testo ed elaborare dati binari interamente nel browser.
Per approfondire, esplora il tipo Blob su cui si basa File e la panoramica più ampia della File API.