Start · Sprachen · JavaScript · Referenz · FileSystemSyncAccessHandle.read()

FileSystemSyncAccessHandle.read()

Methode

Liest synchron Bytes aus der Datei des Handles in einen <code>ArrayBuffer</code> bzw. eine <code>ArrayBufferView</code>, optional ab einer bestimmten Byte-Position.

seit JavaScript Baseline 2023: Chrome 102+, Edge 102+, Firefox 111 Kategorie: webapi

Signatur

FileSystemSyncAccessHandle.prototype.read(buffer, options)

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

Typ
number
Beschreibung
Anzahl der gelesenen Bytes. Ist sie kleiner als 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();
4 OPFS

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'));
{ bytes: 11, sum: 1017 }

// Wichtig · Fallstricke

  • Nur in Dedicated Workers verfügbar: Im Hauptthread, in Shared Workers und Service Workers gibt es createSyncAccessHandle() nicht. Im Hauptthread nutzen Sie stattdessen FileSystemFileHandle.getFile() bzw. createWritable().
  • Nur für OPFS: Die Methode funktioniert nur mit Dateien aus navigator.storage.getDirectory(), nicht mit Dateien, die der Nutzer über showOpenFilePicker() 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 mit await läuft zwar weiter, ist aber überflüssig.
  • Exklusive Sperre: Ein offenes Sync-Handle sperrt die Datei. Weitere createSyncAccessHandle()-Aufrufe schlagen mit NoModificationAllowedError fehl. Rufen Sie deshalb immer close() auf, am besten in einem finally-Block.
  • Nach close() wirft read() einen InvalidStateError. Übergeben Sie einen Puffer, der kein ArrayBuffer und keine View ist, folgt ein TypeError.
  • Ohne at hängt das Ergebnis von der internen Dateiposition ab, die sich read() und write() teilen. Geben Sie at ausdrü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.