Signatur
Beschreibung
Mit write() schreibt man Inhalte in eine Datei, die man vorher über FileSystemFileHandle.createWritable() geöffnet hat. Die Daten landen an der aktuellen Cursor-Position. Nach jedem Schreibvorgang rückt der Cursor um die Anzahl der geschriebenen Bytes weiter. Man kann Zeichenketten, ArrayBuffer, TypedArray, DataView und Blob übergeben.
Statt der Rohdaten kann man auch ein Befehlsobjekt übergeben. Es hat die Eigenschaft type mit einem der Werte "write", "seek" oder "truncate". So lässt sich an einer bestimmten Stelle (position) schreiben, der Cursor versetzen oder die Datei auf eine bestimmte Länge (size) kürzen bzw. verlängern.
Wichtig: Die Änderungen werden zuerst in eine temporäre Datei geschrieben. In der Zieldatei erscheinen sie erst, wenn man den Stream mit close() schließt. Wird der Stream abgebrochen (abort()) oder die Seite geschlossen, bevor close() fertig ist, gehen die Änderungen verloren. Beim Origin Private File System (OPFS) gilt dieselbe Regel.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $data Pflicht | string | ArrayBuffer | TypedArray | DataView | Blob | WriteParams | Die zu schreibenden Daten oder ein Befehlsobjekt WriteParams mit folgenden Eigenschaften:
|
Rückgabewert
undefined erfüllt wird, sobald die Daten in die temporäre Datei geschrieben sind. Das Promise wird abgelehnt mit NotAllowedError (Berechtigung fehlt), QuotaExceededError (Speicherplatz reicht nicht), TypeError (ungültige Daten oder Befehlsobjekt ohne Pflichtfeld) oder InvalidStateError (Stream bereits geschlossen oder abgebrochen).Beispiele
Text in eine vom Nutzer gewählte Datei speichern
const saveButton = document.querySelector('#save');
saveButton.addEventListener('click', async () => {
// Speichern-Dialog öffnen (benötigt eine Nutzeraktion)
const handle = await window.showSaveFilePicker({
suggestedName: 'notizen.txt',
types: [{ description: 'Textdatei', accept: { 'text/plain': ['.txt'] } }]
});
const writable = await handle.createWritable();
await writable.write('Einkaufsliste:\n- Milch\n- Brot\n');
await writable.close(); // erst jetzt wird die Datei wirklich geschrieben
console.log('Gespeichert:', handle.name);
});
Befehlsobjekte: an Position schreiben, Cursor setzen, kürzen
const root = await navigator.storage.getDirectory(); // OPFS
const handle = await root.getFileHandle('daten.txt', { create: true });
const writable = await handle.createWritable();
await writable.write('Hallo Welt!');
// An Byte 6 überschreiben
await writable.write({ type: 'write', position: 6, data: 'Leute' });
// Cursor ans Ende setzen und anhängen
await writable.write({ type: 'seek', position: 11 });
await writable.write(' :)');
// Datei auf 14 Bytes kürzen
await writable.write({ type: 'truncate', size: 14 });
await writable.close();
const file = await handle.getFile();
console.log(await file.text());
An bestehende Datei anhängen (keepExistingData)
const root = await navigator.storage.getDirectory();
const handle = await root.getFileHandle('log.txt', { create: true });
const appendLine = async (line) => {
const file = await handle.getFile();
const writable = await handle.createWritable({ keepExistingData: true });
await writable.seek(file.size); // Cursor ans Dateiende
await writable.write(`${new Date().toISOString()} ${line}\n`);
await writable.close();
};
await appendLine('App gestartet');
await appendLine('Nutzer angemeldet');
console.log(await (await handle.getFile()).text());
Binärdaten und Blob aus fetch() schreiben
const root = await navigator.storage.getDirectory();
const handle = await root.getFileHandle('bild.png', { create: true });
const writable = await handle.createWritable();
const response = await fetch('/img/logo.png');
const blob = await response.blob();
await writable.write(blob);
await writable.close();
// Alternativ ohne Zwischenspeicher: await response.body.pipeTo(writable);
console.log('Größe:', (await handle.getFile()).size, 'Bytes');
// Wichtig · Fallstricke
- Ohne
close()kein Ergebnis: Was man mitwrite()schreibt, landet zunächst in einer temporären Datei. Vergisst manawait writable.close(), bleibt die Zieldatei unverändert. Verwende deshalbtry/finallyoder rufe im Fehlerfallabort()auf. - Datei wird standardmäßig geleert:
createWritable()ohne{ keepExistingData: true }beginnt mit einer leeren Datei. Wer an eine Datei anhängen will, braucht diese Option und muss zusätzlich den Cursor mitseek()ans Dateiende setzen. - Schreibt man über das Dateiende hinaus (
position> Dateigröße), füllt der Browser die Lücke mit Null-Bytes. Das Gleiche gilt, wenntruncatedie Datei verlängert. - Zeichenketten werden immer als UTF-8 kodiert.
- Die Methoden
seek(position)undtruncate(size)sind Kurzformen für die entsprechenden Befehlsobjekte. - Rufe
write()nacheinander mitawaitauf. Der Stream arbeitet die Aufrufe zwar der Reihe nach ab, ein abgelehntes Promise übersieht man ohneawaitaber leicht. - Kompatibilität: Funktioniert nur in sicheren Kontexten (HTTPS).
showSaveFilePicker()gibt es nur in Chromium-Browsern. In Firefox und Safari funktioniertwrite()nur mit dem Origin Private File System (navigator.storage.getDirectory()). Für Worker mit hohem Datendurchsatz eignet sich im OPFS eherFileSystemSyncAccessHandle.