Signatur
Beschreibung
read() liest Daten aus einer Datei im Origin Private File System (OPFS) direkt in einen vorhandenen Puffer. Die Methode arbeitet synchron und blockiert daher den aufrufenden Thread, bis der Lesevorgang fertig ist. Deshalb gibt es sie nur in Dedicated Web Workers, wo Blockieren die Oberfläche nicht einfriert.
Es werden höchstens so viele Bytes gelesen, wie in den Zielpuffer passen (buffer.byteLength). Ohne at liest die Methode ab der aktuellen Dateiposition, die nach jedem read() bzw. write() um die Anzahl der verarbeiteten Bytes weiterrückt. Mit options.at legen Sie einen festen Offset fest; so ist wahlfreier Zugriff möglich, etwa für Datenbank-Seiten, Indexstrukturen oder WebAssembly-Portierungen wie SQLite.
Der Rückgabewert ist die Anzahl der tatsächlich gelesenen Bytes. Sie kann kleiner als die Puffergröße sein, wenn das Dateiende erreicht ist, und ist 0, wenn ab dem Offset keine Daten mehr vorliegen. Werten Sie diesen Wert immer aus, statt den ganzen Puffer als gültig zu betrachten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $buffer Pflicht | ArrayBuffer | ArrayBufferView (z. B. Uint8Array, DataView) | Zielpuffer, in den die gelesenen Bytes geschrieben werden. Seine Größe (byteLength) bestimmt, wie viele Bytes höchstens gelesen werden. |
|
| $options | object | {} | Optionales Objekt mit Leseoptionen. |
| $options.at | number | aktuelle Dateiposition | Byte-Offset in der Datei, ab dem gelesen wird. Ohne Angabe wird ab der aktuellen Dateiposition gelesen. |
Rückgabewert
buffer.byteLength, wurde das Dateiende erreicht; 0 heißt, dass keine Daten mehr gelesen wurden.Beispiele
Komplette Datei im Worker lesen und als Text dekodieren
// worker.js – läuft in einem Dedicated Worker
const readTextFile = async (name) => {
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle(name, { create: true });
const access = await fileHandle.createSyncAccessHandle();
try {
const size = access.getSize();
const buffer = new Uint8Array(size);
const bytesRead = access.read(buffer, { at: 0 });
return new TextDecoder().decode(buffer.subarray(0, bytesRead));
} finally {
access.close(); // Sperre auf der Datei wieder freigeben
}
};
readTextFile('notizen.txt').then((text) => postMessage(text));
Schreiben und an einem bestimmten Offset zurücklesen
// worker.js
const root = await navigator.storage.getDirectory();
const handle = await root.getFileHandle('demo.bin', { create: true });
const access = await handle.createSyncAccessHandle();
const encoder = new TextEncoder();
access.truncate(0);
access.write(encoder.encode('Hallo OPFS!'), { at: 0 });
access.flush();
// Nur die 4 Bytes ab Offset 6 lesen
const part = new Uint8Array(4);
const n = access.read(part, { at: 6 });
console.log(n, new TextDecoder().decode(part));
access.close();
Große Datei in Blöcken verarbeiten
// worker.js – z. B. Prüfsumme über eine große Datei bilden
const CHUNK = 64 * 1024;
const sumBytes = async (name) => {
const root = await navigator.storage.getDirectory();
const handle = await root.getFileHandle(name);
const access = await handle.createSyncAccessHandle();
const chunk = new Uint8Array(CHUNK);
let offset = 0;
let sum = 0;
try {
while (true) {
const n = access.read(chunk, { at: offset });
if (n === 0) break; // Dateiende
for (let i = 0; i < n; i++) sum = (sum + chunk[i]) >>> 0;
offset += n;
}
} finally {
access.close();
}
return { bytes: offset, sum };
};
console.log(await sumBytes('demo.bin'));
// Wichtig · Fallstricke
- Nur in Dedicated Workers verfügbar: Im Hauptthread, in Shared Workers und Service Workers gibt es
createSyncAccessHandle()nicht. Im Hauptthread nutzen Sie stattdessenFileSystemFileHandle.getFile()bzw.createWritable(). - Nur für OPFS: Die Methode funktioniert nur mit Dateien aus
navigator.storage.getDirectory(), nicht mit Dateien, die der Nutzer übershowOpenFilePicker()auswählt. - Nicht mehr asynchron: In frühen Chromium-Versionen (vor 108) gaben
read(),getSize()usw. ein Promise zurück. Heute sind sie synchron. Älterer Code mitawaitläuft zwar weiter, ist aber überflüssig. - Exklusive Sperre: Ein offenes Sync-Handle sperrt die Datei. Weitere
createSyncAccessHandle()-Aufrufe schlagen mitNoModificationAllowedErrorfehl. Rufen Sie deshalb immerclose()auf, am besten in einemfinally-Block. - Nach
close()wirftread()einenInvalidStateError. Übergeben Sie einen Puffer, der keinArrayBufferund keine View ist, folgt einTypeError. - Ohne
athängt das Ergebnis von der internen Dateiposition ab, die sichread()undwrite()teilen. Geben Sieatausdrücklich an, dann ist das Verhalten eindeutig. - Wegen des synchronen Zugriffs ist die Methode deutlich schneller als die asynchronen File-System-APIs. Damit eignet sie sich besonders für WebAssembly-Anwendungen wie SQLite-Wasm.