Start · Sprachen · JavaScript · Referenz · FileReader

FileReader

Schnittstelle

Liest den Inhalt von <code>File</code>- oder <code>Blob</code>-Objekten asynchron als Text, Data-URL oder <code>ArrayBuffer</code> und meldet den Fortschritt über Events.

seit JavaScript Baseline: alle Browser (seit ca. 2012); auch in We Kategorie: webapi

Signatur

interface FileReader extends EventTarget

Beschreibung

FileReader liest Dateien, die der Nutzer z. B. über <input type="file"> oder per Drag & Drop ausgewählt hat, sowie beliebige Blob-Objekte. Auf das Dateisystem hat die API keinen freien Zugriff. Sie kann nur Daten lesen, die ihr ausdrücklich übergeben wurden.

Das Lesen läuft asynchron und ereignisbasiert. Du startest es mit einer der Methoden readAsText(), readAsDataURL(), readAsArrayBuffer() oder dem veralteten readAsBinaryString(). Das Ergebnis steht danach in reader.result bereit. Den Ablauf meldet der Reader über diese Events:

  • loadstart: Das Lesen hat begonnen.
  • progress: Es wurden weitere Daten gelesen.
  • load: Das Lesen war erfolgreich.
  • error: Das Lesen ist fehlgeschlagen.
  • abort: Das Lesen wurde abgebrochen.
  • loadend: Das Lesen ist beendet, egal ob erfolgreich oder nicht.

Weitere wichtige Eigenschaften sind readyState mit den Werten EMPTY = 0, LOADING = 1 und DONE = 2 sowie error, das bei einem Fehler eine DOMException enthält. Mit abort() brichst du einen laufenden Lesevorgang ab.

In modernem Code sind oft die Promise-basierten Methoden Blob.prototype.text(), arrayBuffer() und stream() die bessere Wahl. FileReader brauchst du vor allem dann, wenn du Fortschrittsanzeigen über progress-Events willst oder eine Data-URL erzeugen musst.

Parameter

Name Typ Default Beschreibung
$(keine) — Der Konstruktor new FileReader() hat keine Parameter. Was gelesen wird, übergibst du erst beim Aufruf der readAs…()-Methoden: ein Blob bzw. File, bei readAsText(blob, encoding) optional zusätzlich die Zeichenkodierung (Standard "UTF-8").

Rückgabewert

Typ
FileReader
Beschreibung
Eine neue FileReader-Instanz mit readyState === 0 (EMPTY) und result === null.

Beispiele

Textdatei aus einem Datei-Input lesen

const input = document.querySelector('#datei');

input.addEventListener('change', () => {
  const [file] = input.files;
  if (!file) return;

  const reader = new FileReader();
  reader.addEventListener('load', () => {
    console.log(`Gelesen: ${file.name}`);
    console.log(reader.result.slice(0, 100)); // die ersten 100 Zeichen
  });
  reader.addEventListener('error', () => {
    console.error('Lesefehler:', reader.error);
  });

  reader.readAsText(file, 'UTF-8');
});
Gelesen: notizen.txt (die ersten 100 Zeichen der Datei)

Bildvorschau per Data-URL

const input = document.querySelector('#bild');
const vorschau = document.querySelector('#vorschau'); // <img>

input.onchange = () => {
  const file = input.files[0];
  if (!file?.type.startsWith('image/')) return;

  const reader = new FileReader();
  reader.onload = () => {
    vorschau.src = reader.result; // "data:image/png;base64,..."
  };
  reader.readAsDataURL(file);
};

Promise-Wrapper mit Fortschrittsanzeige

const readAsArrayBuffer = (blob, onProgress) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onprogress = (e) => {
      if (e.lengthComputable) onProgress?.(Math.round((e.loaded / e.total) * 100));
    };
    reader.onload = () => resolve(reader.result);
    reader.onerror = () => reject(reader.error);
    reader.onabort = () => reject(new DOMException('Abgebrochen', 'AbortError'));
    reader.readAsArrayBuffer(blob);
  });

const blob = new Blob([new Uint8Array([0x89, 0x50, 0x4e, 0x47])]);
const buffer = await readAsArrayBuffer(blob, (p) => console.log(`${p} %`));
const bytes = new Uint8Array(buffer);
console.log([...bytes].map((b) => b.toString(16)).join(' '));
100 % 89 50 4e 47

Lesevorgang abbrechen

const reader = new FileReader();
reader.onabort = () => console.log('Lesen abgebrochen, readyState:', reader.readyState);
reader.onloadend = () => console.log('loadend, result:', reader.result);

reader.readAsText(new Blob(['x'.repeat(10_000_000)]));
reader.abort();
Lesen abgebrochen, readyState: 2 loadend, result: null

// Wichtig · Fallstricke

  • Nur ein Lesevorgang pro Instanz: Rufst du eine readAs…()-Methode auf, während der Reader noch liest (readyState === LOADING), wird eine InvalidStateError-DOMException ausgelöst. Für mehrere Dateien brauchst du daher jeweils einen eigenen Reader oder musst nacheinander lesen.
  • result erst nach load verwenden: Direkt nach dem Aufruf von readAs…() ist result noch null. Das ist ein häufiger Anfängerfehler.
  • Moderne Alternativen: await file.text() und await file.arrayBuffer() sind kürzer und arbeiten mit Promises. Für Bildvorschauen ist URL.createObjectURL(file) meist schneller und speichersparender als eine Data-URL. Gib die erzeugte URL danach mit URL.revokeObjectURL() wieder frei.
  • Speicher: readAsDataURL() vergrößert die Daten durch Base64 um rund 33 %. Große Dateien liest du besser stückweise mit blob.slice() oder blob.stream().
  • Veraltet: readAsBinaryString() solltest du nicht mehr verwenden. Nimm stattdessen readAsArrayBuffer().
  • Sicherheit: Dateiinhalte stammen vom Nutzer und sind nicht vertrauenswürdig. Gelesenen Text nie per innerHTML einfügen, sondern textContent verwenden, sonst droht XSS. Data-URLs mit dem MIME-Typ image/svg+xml oder text/html können Skripte enthalten.
  • Kompatibilität: FileReader funktioniert in allen aktuellen Browsern und in Web Workers. Die synchrone Variante FileReaderSync gibt es nur in Workers. Seit Version 20 bringt auch Node.js FileReader nicht mit. Dort verwendest du stattdessen Blob.prototype.text() und arrayBuffer().