Start · Sprachen · JavaScript · Referenz · FileSystemDirectoryEntry.createReader()

FileSystemDirectoryEntry.createReader()

Methode

Erzeugt ein <code>FileSystemDirectoryReader</code>-Objekt, mit dem sich die Einträge (Dateien und Unterverzeichnisse) eines Verzeichnisses auslesen lassen.

seit JavaScript Baseline: alle modernen Browser (Chrome 13+, Firef Kategorie: webapi

Signatur

FileSystemDirectoryEntry.prototype.createReader()

Beschreibung

Die Methode createReader() des Interfaces FileSystemDirectoryEntry gibt einen FileSystemDirectoryReader zurück. Mit dessen Methode readEntries() liest man die Inhalte des Verzeichnisses als Liste von FileSystemEntry-Objekten aus, also als FileSystemFileEntry für Dateien oder als FileSystemDirectoryEntry für Unterordner.

Typischerweise braucht man die Methode, wenn Nutzer einen ganzen Ordner per Drag & Drop ablegen. Über DataTransferItem.webkitGetAsEntry() erhält man einen Eintrag. Ist dieser ein Verzeichnis (isDirectory === true), liest man seinen Inhalt mit createReader() aus, bei Bedarf rekursiv.

Wichtig: readEntries() liefert die Einträge stückweise. In Chrome kommen zum Beispiel höchstens 100 Einträge pro Aufruf zurück. Man muss readEntries() auf demselben Reader so lange erneut aufrufen, bis ein leeres Array zurückkommt. Ein neuer Reader fängt wieder von vorne an.

Rückgabewert

Typ
FileSystemDirectoryReader
Beschreibung
Ein neuer Reader für das Verzeichnis. Mit seiner Methode readEntries(successCallback, errorCallback) liest man die Einträge des Verzeichnisses in Portionen aus.

Beispiele

Einträge eines abgelegten Ordners auflisten

const dropZone = document.querySelector('#drop-zone');

dropZone.addEventListener('dragover', (e) => e.preventDefault());

dropZone.addEventListener('drop', (e) => {
  e.preventDefault();
  for (const item of e.dataTransfer.items) {
    const entry = item.webkitGetAsEntry();
    if (entry?.isDirectory) {
      const reader = entry.createReader();
      reader.readEntries(
        (entries) => {
          for (const child of entries) {
            console.log(child.isDirectory ? '📁' : '📄', child.name);
          }
        },
        (err) => console.error('Lesefehler:', err)
      );
    }
  }
});
📄 index.html 📁 css 📄 app.js

Alle Einträge vollständig lesen (Promise-Wrapper mit Schleife)

// readEntries liefert Portionen, darum so lange lesen, bis ein leeres Array kommt
const readBatch = (reader) =>
  new Promise((resolve, reject) => reader.readEntries(resolve, reject));

const readAllEntries = async (dirEntry) => {
  const reader = dirEntry.createReader(); // EIN Reader für alle Aufrufe
  const all = [];
  let batch;
  do {
    batch = await readBatch(reader);
    all.push(...batch);
  } while (batch.length > 0);
  return all;
};

// Verwendung im drop-Handler:
// const entries = await readAllEntries(entry);
// console.log(`${entries.length} Einträge gefunden`);
250 Einträge gefunden

Ordner rekursiv durchlaufen und File-Objekte sammeln

const readBatch = (reader) =>
  new Promise((resolve, reject) => reader.readEntries(resolve, reject));

const getFile = (fileEntry) =>
  new Promise((resolve, reject) => fileEntry.file(resolve, reject));

const collectFiles = async (entry) => {
  if (entry.isFile) {
    const file = await getFile(entry);
    return [{ path: entry.fullPath, file }];
  }
  const reader = entry.createReader();
  const results = [];
  let batch;
  while ((batch = await readBatch(reader)).length > 0) {
    for (const child of batch) {
      results.push(...(await collectFiles(child)));
    }
  }
  return results;
};

document.body.addEventListener('dragover', (e) => e.preventDefault());
document.body.addEventListener('drop', async (e) => {
  e.preventDefault();
  // Einträge synchron holen: nach dem ersten await ist dataTransfer leer
  const entries = [...e.dataTransfer.items]
    .map((item) => item.webkitGetAsEntry())
    .filter(Boolean);
  for (const entry of entries) {
    const files = await collectFiles(entry);
    files.forEach(({ path, file }) => console.log(path, file.size, 'Bytes'));
  }
});
/projekt/index.html 1024 Bytes /projekt/css/style.css 2048 Bytes

// Wichtig · Fallstricke

  • Einträge kommen in Portionen: Ein einzelner readEntries()-Aufruf liefert oft nicht alle Einträge. In Chrome sind es höchstens 100. Rufen Sie readEntries() auf demselben Reader so lange auf, bis ein leeres Array kommt. Wenn Sie für jeden Aufruf mit createReader() einen neuen Reader erzeugen, bekommen Sie immer wieder dieselbe erste Portion und damit eine Endlosschleife.
  • DataTransfer nur synchron nutzbar: Rufen Sie webkitGetAsEntry() im drop-Handler vor dem ersten await auf. Danach ist die DataTransferItemList leer.
  • Nur Callbacks: Die API arbeitet mit Callbacks und nicht mit Promises. Für async/await brauchen Sie einen eigenen Wrapper.
  • Kompatibilität: Die API ist Teil der nicht standardisierten, nur teilweise umgesetzten File and Directory Entries API. Über Drag & Drop und <input type="file" webkitdirectory> funktioniert sie in allen modernen Browsern. Für neue Projekte mit Schreibzugriff ist die File System Access API (FileSystemDirectoryHandle) besser geeignet, die es allerdings nicht in allen Browsern gibt.
  • Die Reihenfolge der Einträge ist nicht festgelegt. Sortieren Sie bei Bedarf selbst, zum Beispiel nach name.