Signatur
Beschreibung
flush() sorgt dafür, dass Daten, die mit FileSystemSyncAccessHandle.write() geschrieben wurden, tatsächlich dauerhaft gespeichert werden. Der Browser bzw. das Betriebssystem darf Schreibvorgänge zwischenpuffern; erst nach flush() ist sichergestellt, dass ein Absturz oder ein Schließen des Tabs die Änderungen nicht mehr verliert. Die Methode ist das Gegenstück zu fsync() in klassischen Dateisystem-APIs.
Die Methode steht ausschließlich im Origin Private File System (OPFS) und nur in dedizierten Web Workern zur Verfügung, da FileSystemSyncAccessHandle synchron arbeitet und den Haupt-Thread sonst blockieren würde. Ein Handle erhält man über FileSystemFileHandle.createSyncAccessHandle().
Typische Einsatzfälle sind Datenbank-Engines im Browser (z. B. SQLite über WebAssembly), Journal- oder Log-Dateien und jede Anwendung, die an definierten Punkten (Transaktionsende, Checkpoint) Datenkonsistenz garantieren muss. flush() ist vergleichsweise teuer – man ruft es daher gezielt nach einer Gruppe von Schreibvorgängen auf, nicht nach jedem einzelnen write().
Rückgabewert
Promise<undefined>.Beispiele
Text in eine OPFS-Datei schreiben und sichern (im Worker)
// worker.js – läuft in einem dedizierten Web Worker
const saveNote = async (text) => {
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('notiz.txt', { create: true });
const access = await fileHandle.createSyncAccessHandle();
try {
const data = new TextEncoder().encode(text);
access.truncate(0); // alten Inhalt verwerfen
const written = access.write(data, { at: 0 });
access.flush(); // dauerhaft auf den Datenträger schreiben
console.log(`${written} Bytes gesichert, Dateigröße: ${access.getSize()}`);
} finally {
access.close(); // Sperre auf die Datei freigeben
}
};
saveNote('Hallo OPFS!');
Log-Einträge sammeln und gebündelt flushen
// worker.js
const encoder = new TextEncoder();
let access;
let pending = 0;
const openLog = async () => {
const root = await navigator.storage.getDirectory();
const handle = await root.getFileHandle('app.log', { create: true });
access = await handle.createSyncAccessHandle();
};
const log = (message) => {
const line = encoder.encode(`${new Date().toISOString()} ${message}\n`);
access.write(line, { at: access.getSize() }); // anhängen
pending++;
// Nur alle 50 Einträge flushen – spart teure Datenträgerzugriffe
if (pending >= 50) {
access.flush();
pending = 0;
}
};
await openLog();
for (let i = 0; i < 120; i++) log(`Ereignis ${i}`);
access.flush(); // Rest sichern
access.close();
console.log('Log geschrieben');
Haupt-Thread steuert den Worker per postMessage
// main.js
const worker = new Worker('storage-worker.js');
worker.onmessage = ({ data }) => console.log('Worker:', data);
worker.postMessage({ file: 'daten.json', content: JSON.stringify({ id: 1 }) });
// storage-worker.js
self.onmessage = async ({ data: { file, content } }) => {
const root = await navigator.storage.getDirectory();
const fh = await root.getFileHandle(file, { create: true });
const access = await fh.createSyncAccessHandle();
try {
access.truncate(0);
access.write(new TextEncoder().encode(content), { at: 0 });
access.flush();
self.postMessage('gespeichert');
} catch (err) {
self.postMessage(`Fehler: ${err.name}`);
} finally {
access.close();
}
};
// Wichtig · Fallstricke
- Nur in dedizierten Web Workern: Im Haupt-Thread, in Shared Workern und in Service Workern gibt es
createSyncAccessHandle()nicht. - InvalidStateError: Wird ausgelöst, wenn
flush()nachclose()aufgerufen wird. - Synchron statt asynchron: Chromium vor Version 108 lieferte ein Promise. Wer alte Versionen unterstützen muss, kann
await access.flush()schreiben – bei einem synchronen Rückgabewert (undefined) schadet das nicht. - Performance: Jeder Aufruf erzwingt einen Datenträgerzugriff. Nach jedem kleinen
write()zu flushen bremst stark; besser an Transaktions- oder Checkpoint-Grenzen flushen. - close() ersetzt flush() nicht zuverlässig: Beim Schließen werden die Daten zwar in der Regel gespeichert, für garantierte Dauerhaftigkeit an definierten Punkten sollte man aber ausdrücklich
flush()aufrufen. - Das Handle sperrt die Datei exklusiv; solange es offen ist, schlagen weitere
createSyncAccessHandle()- odercreateWritable()-Aufrufe auf dieselbe Datei fehl (NoModificationAllowedError). - Setzt einen sicheren Kontext (HTTPS) voraus.