Signatur
Beschreibung
FileSystemFileHandle ist Teil der File System API und steht für eine einzelne Datei. Ein Handle ist nicht die Datei selbst, sondern ein Verweis darauf. Er erbt von FileSystemHandle die Eigenschaften kind (immer "file") und name sowie die Methoden isSameEntry(), queryPermission() und requestPermission().
Einen Handle bekommt man auf mehreren Wegen:
- über
window.showOpenFilePicker()bzw.window.showSaveFilePicker()(File System Access API, nur Chromium), - über
FileSystemDirectoryHandle.getFileHandle(), etwa im Origin Private File System (OPFS) übernavigator.storage.getDirectory(), - über Drag & Drop mit
DataTransferItem.getAsFileSystemHandle().
Die wichtigsten Methoden:
getFile(): gibt einPromise<File>mit einer Momentaufnahme des Inhalts zurück.createWritable(options): gibt einPromise<FileSystemWritableFileStream>zum Schreiben zurück. Die Änderungen landen erst beiclose()in der Datei.createSyncAccessHandle(options): gibt einPromise<FileSystemSyncAccessHandle>für sehr schnelle, synchrone Lese- und Schreibzugriffe zurück. Das geht nur im OPFS und nur in Dedicated Workers.
Typische Einsatzfälle sind Editoren im Browser, die eine lokale Datei öffnen und wieder speichern („Speichern“ statt „Herunterladen“), sowie leistungsstarke Speicherung im OPFS, etwa für SQLite-WASM oder Offline-Caches.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options.keepExistingData | boolean | false | Option für createWritable(). Bei true wird der bisherige Inhalt in die temporäre Datei kopiert, sodass man anhängen oder punktuell überschreiben kann. Bei false beginnt man mit einer leeren Datei. |
| $options.mode | "exclusive" | "siloed" | "read-only" | "readwrite" | "readwrite-unsafe" | "siloed" (createWritable) bzw. "readwrite" (createSyncAccessHandle) | Sperrmodus, bislang nur in Chromium (ab 121) unterstützt. Für createWritable() sind "exclusive" und "siloed" erlaubt, für createSyncAccessHandle() die Werte "readwrite", "read-only" und "readwrite-unsafe". |
Rückgabewert
getFileHandle() oder über Drag & Drop. Seine Methoden liefern Promise<File>, Promise<FileSystemWritableFileStream> bzw. Promise<FileSystemSyncAccessHandle>.Beispiele
Lokale Textdatei öffnen und lesen (File System Access API)
// Muss durch eine Nutzeraktion ausgelöst werden, z. B. einen Klick
const openButton = document.querySelector('#open');
openButton.addEventListener('click', async () => {
try {
const [fileHandle] = await window.showOpenFilePicker({
types: [{ description: 'Textdateien', accept: { 'text/plain': ['.txt', '.md'] } }],
});
console.log(fileHandle.kind, fileHandle.name);
const file = await fileHandle.getFile();
const text = await file.text();
console.log(`${file.size} Bytes gelesen`);
document.querySelector('#editor').value = text;
} catch (err) {
if (err.name !== 'AbortError') console.error(err);
}
});
Änderungen zurück in dieselbe Datei speichern
const saveFile = async (fileHandle, contents) => {
// Berechtigung prüfen und bei Bedarf anfordern
const opts = { mode: 'readwrite' };
if ((await fileHandle.queryPermission(opts)) !== 'granted' &&
(await fileHandle.requestPermission(opts)) !== 'granted') {
throw new Error('Keine Schreibberechtigung');
}
const writable = await fileHandle.createWritable();
await writable.write(contents);
await writable.close(); // erst jetzt wird die Datei tatsächlich ersetzt
console.log(`Gespeichert: ${fileHandle.name}`);
};
// Aufruf, z. B. nach showSaveFilePicker():
// const handle = await window.showSaveFilePicker({ suggestedName: 'export.json' });
// await saveFile(handle, JSON.stringify({ ok: true }, null, 2));
Origin Private File System: Datei anlegen, anhängen, lesen
// Läuft in allen modernen Browsern, ohne Picker und ohne Berechtigungsdialog
const root = await navigator.storage.getDirectory();
const logHandle = await root.getFileHandle('app.log', { create: true });
const writable = await logHandle.createWritable({ keepExistingData: true });
const { size } = await logHandle.getFile();
await writable.seek(size); // ans Dateiende springen
await writable.write(`${new Date().toISOString()} App gestartet\n`);
await writable.close();
const log = await (await logHandle.getFile()).text();
console.log(log.trim().split('\n').at(-1));
Synchroner Zugriff im Dedicated Worker
// worker.js
self.onmessage = async ({ data }) => {
const root = await navigator.storage.getDirectory();
const handle = await root.getFileHandle('daten.bin', { create: true });
const access = await handle.createSyncAccessHandle();
const bytes = new TextEncoder().encode(data);
access.truncate(0);
access.write(bytes, { at: 0 });
access.flush();
const buffer = new Uint8Array(access.getSize());
access.read(buffer, { at: 0 });
access.close(); // Sperre wieder freigeben
self.postMessage(new TextDecoder().decode(buffer));
};