Start · Sprachen · JavaScript · Referenz · FileSystemDirectoryHandle.entries()

FileSystemDirectoryHandle.entries()

Methode

Gibt einen asynchronen Iterator über die <code>[name, handle]</code>-Paare aller direkten Einträge eines Verzeichnisses zurück.

seit JavaScript Baseline 2023 (OPFS): Chrome 86+, Edge 86+, Firefo Kategorie: webapi

Signatur

FileSystemDirectoryHandle.prototype.entries()

Beschreibung

Die Methode entries() von FileSystemDirectoryHandle liefert einen asynchronen Iterator. Jeder Schritt ergibt ein Array [name, handle]. name ist der Datei- oder Verzeichnisname als String, handle ist ein FileSystemFileHandle oder ein FileSystemDirectoryHandle. So können Sie den Inhalt eines Verzeichnisses durchlaufen, ohne die Namen vorher kennen zu müssen.

Am einfachsten nutzen Sie den Iterator mit for await...of. entries() entspricht dem Standard-Iterator des Handles (handle[Symbol.asyncIterator]). Deshalb liefert for await (const [name, h] of dirHandle) dasselbe Ergebnis. Brauchen Sie nur die Namen, nehmen Sie keys(). Brauchen Sie nur die Handles, nehmen Sie values().

Die Methode listet nur die direkten Kinder auf. Für eine rekursive Suche prüfen Sie handle.kind === 'directory' und rufen entries() auf dem Unterverzeichnis erneut auf. Die Reihenfolge der Einträge ist nicht festgelegt und kann je nach Browser und Dateisystem anders sein.

Typische Einsatzfälle sind:

  • Dateien im Origin Private File System (OPFS) auflisten, das Sie über navigator.storage.getDirectory() erreichen
  • ein vom Nutzer ausgewähltes Verzeichnis durchlaufen, das Sie über window.showDirectoryPicker() erhalten (nur Chromium)

Rückgabewert

Typ
AsyncIterableIterator<[string, FileSystemFileHandle | FileSystemDirectoryHandle]>
Beschreibung
Ein asynchroner Iterator. Jeder Aufruf von next() gibt ein Promise zurück. Es erfüllt sich mit { value: [name, handle], done: false } oder am Ende mit { done: true }.

Beispiele

Inhalt des Origin Private File System auflisten

const root = await navigator.storage.getDirectory();

// Testdatei anlegen
await root.getFileHandle('notizen.txt', { create: true });
await root.getDirectoryHandle('bilder', { create: true });

for await (const [name, handle] of root.entries()) {
  console.log(`${handle.kind}: ${name}`);
}
file: notizen.txt directory: bilder

Verzeichnis rekursiv durchlaufen und Pfade sammeln

const walk = async (dirHandle, path = '') => {
  const result = [];
  for await (const [name, handle] of dirHandle.entries()) {
    const fullPath = `${path}/${name}`;
    if (handle.kind === 'directory') {
      result.push(...await walk(handle, fullPath));
    } else {
      result.push(fullPath);
    }
  }
  return result;
};

const root = await navigator.storage.getDirectory();
console.log(await walk(root));
["/notizen.txt", "/bilder/foto.png"]

Gesamtgröße aller Dateien eines Verzeichnisses berechnen

const getTotalSize = async (dirHandle) => {
  let total = 0;
  for await (const [, handle] of dirHandle.entries()) {
    if (handle.kind === 'file') {
      const file = await handle.getFile();
      total += file.size;
    }
  }
  return total;
};

const root = await navigator.storage.getDirectory();
console.log(`Belegt: ${await getTotalSize(root)} Bytes`);
Belegt: 2048 Bytes

Vom Nutzer gewähltes Verzeichnis einlesen (Chromium)

document.querySelector('#open').addEventListener('click', async () => {
  const dir = await window.showDirectoryPicker();
  // Iterator mit Array.fromAsync in ein Array umwandeln (ES2024)
  const entries = await Array.fromAsync(dir.entries());
  console.log(entries.map(([name]) => name));
});
["index.html", "style.css", "src"]

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: Die API funktioniert nur über HTTPS oder localhost.
  • Browserunterstützung: Im OPFS (navigator.storage.getDirectory()) funktioniert die Methode in allen modernen Browsern. showDirectoryPicker() gibt es dagegen nur in Chromium-Browsern. Firefox und Safari unterstützen es nicht.
  • Keine feste Reihenfolge: Wenn Sie eine sortierte Ausgabe brauchen, sammeln Sie die Einträge zuerst und sortieren Sie sie danach, z. B. mit localeCompare.
  • Ändern während der Iteration: Wenn Sie während des Durchlaufs Einträge anlegen oder löschen, ist nicht festgelegt, ob diese im Iterator auftauchen. Sammeln Sie deshalb erst alle Einträge und ändern Sie sie danach.
  • Fehler: Das Promise von next() wird abgelehnt:
    • mit NotAllowedError, wenn die Leseberechtigung fehlt (bei vom Nutzer gewählten Verzeichnissen, siehe queryPermission() und requestPermission())
    • mit NotFoundError, wenn das Verzeichnis nicht mehr existiert
  • Nutzen Sie kein normales for...of, sondern for await...of. Der Iterator ist asynchron, ein synchroner Durchlauf wirft einen TypeError.
  • Array.fromAsync() ist Teil von ES2024. In älteren Umgebungen müssen Sie die Einträge per Schleife sammeln.