Signatur
Beschreibung
FileSystemDirectoryHandle gehört zur File System API und erbt von FileSystemHandle. Über ein solches Handle greift man auf ein Verzeichnis zu. Das kann ein Ordner sein, den der Nutzer über window.showDirectoryPicker() ausgewählt hat. Es kann aber auch das Wurzelverzeichnis des Origin Private File System (OPFS) sein, das man über navigator.storage.getDirectory() erhält.
Die wichtigsten Methoden:
getFileHandle(name, { create })gibt einFileSystemFileHandlefür eine Datei im Verzeichnis zurück und legt die Datei bei Bedarf an.getDirectoryHandle(name, { create })gibt ein Handle für einen Unterordner zurück und legt ihn bei Bedarf an.removeEntry(name, { recursive })löscht eine Datei oder einen Ordner.resolve(possibleDescendant)liefert den relativen Pfad zu einem untergeordneten Handle als Array von Namen. Ist das Handle kein Nachfahre, ist das Ergebnisnull.entries(),keys(),values()und[Symbol.asyncIterator]sind asynchrone Iteratoren über den Inhalt des Verzeichnisses. Man nutzt sie mitfor await…of.
Die Schnittstelle eignet sich für Editoren, Foto- oder Projektverwaltungen, die mit lokalen Ordnern arbeiten. Im OPFS dient sie als schneller, privater Speicher, zum Beispiel für SQLite-Datenbanken in WebAssembly. Alle Methoden arbeiten asynchron und geben Promises zurück. Die geerbten Eigenschaften kind (hier immer "directory") und name beschreiben das Handle.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Name des Eintrags im Verzeichnis. Wird von getFileHandle(), getDirectoryHandle() und removeEntry() verwendet. Pfade mit / sind nicht erlaubt. |
|
| $options.create | boolean | false | Bei getFileHandle()/getDirectoryHandle(): legt den Eintrag an, falls er noch nicht existiert. |
| $options.recursive | boolean | false | Bei removeEntry(): löscht auch Ordner, die nicht leer sind, samt Inhalt. |
| $possibleDescendant | FileSystemHandle | Bei resolve(): das Handle, dessen relativer Pfad bestimmt werden soll. |
Rückgabewert
showDirectoryPicker(), navigator.storage.getDirectory(), getDirectoryHandle() oder DataTransferItem.getAsFileSystemHandle(). Einen öffentlichen Konstruktor gibt es nicht.Beispiele
Datei im Origin Private File System anlegen und lesen
const root = await navigator.storage.getDirectory();
// Unterordner und Datei anlegen (create: true)
const notesDir = await root.getDirectoryHandle('notizen', { create: true });
const fileHandle = await notesDir.getFileHandle('todo.txt', { create: true });
// Schreiben
const writable = await fileHandle.createWritable();
await writable.write('Milch kaufen\nCode reviewen');
await writable.close();
// Lesen
const file = await fileHandle.getFile();
console.log(notesDir.kind, notesDir.name);
console.log(await file.text());
Vom Nutzer gewählten Ordner auflisten
document.querySelector('#open').addEventListener('click', async () => {
try {
const dirHandle = await window.showDirectoryPicker({ mode: 'read' });
for await (const [name, handle] of dirHandle.entries()) {
console.log(handle.kind === 'directory' ? `📁 ${name}` : `📄 ${name}`);
}
} catch (err) {
if (err.name === 'AbortError') console.log('Auswahl abgebrochen');
else throw err;
}
});
Rekursiv alle Dateien sammeln und relativen Pfad ermitteln
const walk = async function* (dir) {
for await (const handle of dir.values()) {
if (handle.kind === 'file') yield handle;
else yield* walk(handle);
}
};
const root = await navigator.storage.getDirectory();
const sub = await root.getDirectoryHandle('a', { create: true });
await sub.getFileHandle('b.txt', { create: true });
for await (const file of walk(root)) {
const path = await root.resolve(file);
console.log(path.join('/'));
}
Einträge löschen
const root = await navigator.storage.getDirectory();
// Einzelne Datei löschen
await root.getDirectoryHandle('a').then((d) => d.removeEntry('b.txt'));
// Ordner inklusive Inhalt löschen
await root.removeEntry('notizen', { recursive: true });
const names = [];
for await (const name of root.keys()) names.push(name);
console.log(names);
// Wichtig · Fallstricke
- Browser-Unterstützung: Das OPFS über
navigator.storage.getDirectory()funktioniert in Chrome, Edge, Firefox und Safari.showDirectoryPicker()für echte Ordner des Nutzers gibt es nur in Chromium-Browsern. Vor der Nutzung sollte man prüfen, ob die Funktion vorhanden ist ('showDirectoryPicker' in window). - Die API ist nur in einem sicheren Kontext (HTTPS) verfügbar.
showDirectoryPicker()braucht außerdem eine Nutzeraktion, etwa einen Klick. Bricht der Nutzer die Auswahl ab, wird einAbortErrorausgelöst. - Die Berechtigungen können wegfallen. Handles lassen sich zwar in IndexedDB speichern. Nach einem Neuladen der Seite muss man die Berechtigung aber mit
queryPermission()prüfen und bei Bedarf mitrequestPermission({ mode: 'readwrite' })neu anfordern (nur Chromium). - Häufige Fehler:
getFileHandle()ohnecreate: truelöst bei einem fehlenden Eintrag einenNotFoundErroraus. Existiert unter dem Namen der falsche Typ (Datei statt Ordner), gibt es einenTypeMismatchError.removeEntry()auf einem nicht leeren Ordner ohnerecursive: truelöst einenInvalidModificationErroraus. - Die Reihenfolge beim Durchlaufen mit
entries()ist nicht festgelegt. Wer sortierte Ausgaben braucht, sortiert selbst. - Das OPFS ist für den Nutzer nicht sichtbar. Der Browser kann es löschen, wenn der Speicher knapp wird. Mit
navigator.storage.persist()lässt sich dauerhafte Speicherung anfordern.