Signatur
Beschreibung
FileSystemHandle ist die gemeinsame Basis von FileSystemFileHandle (Dateien) und FileSystemDirectoryHandle (Verzeichnisse). Man erzeugt es nie direkt mit new, sondern bekommt es von einer anderen Stelle: von window.showOpenFilePicker(), showSaveFilePicker() oder showDirectoryPicker(), von navigator.storage.getDirectory() (Origin Private File System, kurz OPFS), beim Durchlaufen eines Verzeichnis-Handles oder bei Drag & Drop über DataTransferItem.getAsFileSystemHandle().
Das Interface stellt Folgendes bereit:
kind(nur lesbar):"file"oder"directory". Damit unterscheidet man die Art des Eintrags, zum Beispiel beim Durchlaufen eines Verzeichnisses.name(nur lesbar): der Name des Eintrags ohne Pfad.isSameEntry(other): prüft, ob zwei Handles auf denselben Eintrag zeigen. Gibt einPromise<boolean>zurück.queryPermission(descriptor)/requestPermission(descriptor)(experimentell, Chromium): fragen die Lese- oder Schreibberechtigung ab bzw. fordern sie an.remove(options)(nicht standardisiert, Chromium): löscht den Eintrag selbst.
Handles sind serialisierbar. Man kann sie also in IndexedDB speichern oder per postMessage() an Worker schicken. So findet eine Web-App eine zuletzt geöffnete Datei auch nach einem Neuladen der Seite wieder. Die Berechtigung wird dabei aber nicht dauerhaft mitgespeichert. Sie muss später meist neu bestätigt werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $other Pflicht | FileSystemHandle | Parameter von isSameEntry(other): das Handle, mit dem verglichen wird. |
|
| $descriptor | { mode?: 'read' | 'readwrite' } | { mode: 'read' } | Parameter von queryPermission() und requestPermission(). mode legt fest, ob nur Lese- oder auch Schreibrechte geprüft bzw. angefordert werden. |
| $options | { recursive?: boolean } | { recursive: false } | Parameter von remove(options) (nicht standardisiert). Mit recursive: true lassen sich auch Verzeichnisse löschen, die nicht leer sind. |
Rückgabewert
FileSystemFileHandle oder FileSystemDirectoryHandle. isSameEntry() gibt Promise<boolean> zurück, queryPermission() und requestPermission() geben Promise<'granted' | 'denied' | 'prompt'> zurück, remove() gibt Promise<void> zurück.Beispiele
Handle per Datei-Dialog holen und kind/name auswerten (Chromium)
// Muss durch eine Nutzeraktion ausgelöst werden, z. B. einen Klick
document.querySelector('#open').addEventListener('click', async () => {
try {
const [handle] = await window.showOpenFilePicker({
types: [{ description: 'Textdateien', accept: { 'text/plain': ['.txt'] } }]
});
console.log(handle.kind, handle.name);
if (handle.kind === 'file') {
const file = await handle.getFile();
console.log(`${file.size} Bytes`);
}
} catch (err) {
if (err.name !== 'AbortError') throw err; // Nutzer hat abgebrochen
}
});
Origin Private File System: Einträge auflisten und isSameEntry()
const root = await navigator.storage.getDirectory();
const a = await root.getFileHandle('daten.json', { create: true });
await root.getDirectoryHandle('cache', { create: true });
// Verzeichnis durchlaufen – jeder Wert ist ein FileSystemHandle
for await (const handle of root.values()) {
console.log(`${handle.kind === 'directory' ? '📁' : '📄'} ${handle.name}`);
}
// Zeigen zwei Handles auf denselben Eintrag?
const b = await root.getFileHandle('daten.json');
console.log(await a.isSameEntry(b));
console.log(a === b);
Handle in IndexedDB speichern und Berechtigung erneut anfordern
const openDB = () => new Promise((resolve, reject) => {
const req = indexedDB.open('handles', 1);
req.onupgradeneeded = () => req.result.createObjectStore('store');
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
const idb = (mode, fn) => openDB().then(db => new Promise((resolve, reject) => {
const req = fn(db.transaction('store', mode).objectStore('store'));
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
}));
export const saveHandle = handle => idb('readwrite', s => s.put(handle, 'lastFile'));
export const restoreHandle = async () => {
const handle = await idb('readonly', s => s.get('lastFile'));
if (!handle) return null;
const opts = { mode: 'readwrite' };
if ((await handle.queryPermission(opts)) === 'granted') return handle;
// requestPermission braucht eine Nutzeraktion (Klick)
return (await handle.requestPermission(opts)) === 'granted' ? handle : null;
};