Start · Sprachen · JavaScript · Referenz · StorageManager.getDirectory()

StorageManager.getDirectory()

Methode

Liefert ein Promise mit einem <code>FileSystemDirectoryHandle</code> auf das Wurzelverzeichnis des Origin Private File System (OPFS) der aktuellen Herkunft.

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

Signatur

StorageManager.prototype.getDirectory()

Beschreibung

Die Methode getDirectory() der Schnittstelle StorageManager (erreichbar über navigator.storage) gibt Zugriff auf das Origin Private File System (OPFS). Das ist ein privates, virtuelles Dateisystem, das nur die jeweilige Herkunft (Origin) sieht. Der Nutzer sieht es nicht im normalen Dateisystem, und eine Berechtigungsabfrage gibt es auch nicht.

Das zurückgegebene FileSystemDirectoryHandle ist das Wurzelverzeichnis. Darüber legt man mit getFileHandle() und getDirectoryHandle() Dateien und Unterverzeichnisse an oder öffnet sie. Mit removeEntry() löscht man Einträge, und mit for await...of durchläuft man den Inhalt.

Das OPFS eignet sich für große Datenmengen, die schnell gelesen und geschrieben werden müssen. Beispiele sind SQLite-Datenbanken als WebAssembly, Offline-Caches für Medien, Zwischenstände von Editoren oder Spielständen. In einem Dedicated Worker kann man außerdem mit createSyncAccessHandle() synchron und sehr schnell auf Dateien zugreifen.

Die Daten gehören zum normalen Speicherkontingent der Herkunft. Der Browser kann sie wie IndexedDB oder den Cache Storage löschen, wenn Speicher knapp wird. Mit navigator.storage.persist() lässt sich beantragen, dass sie dauerhaft erhalten bleiben.

Rückgabewert

Typ
Promise<FileSystemDirectoryHandle>
Beschreibung
Ein Promise, das mit dem FileSystemDirectoryHandle des OPFS-Wurzelverzeichnisses erfüllt wird. Es wird mit SecurityError abgelehnt, wenn der Zugriff nicht erlaubt ist, z. B. in manchen privaten Fenstern oder wenn der Nutzer Speicher für die Seite gesperrt hat.

Beispiele

Datei im OPFS schreiben und wieder lesen

const saveNote = async (name, text) => {
  const root = await navigator.storage.getDirectory();
  // Datei anlegen, falls sie noch nicht existiert
  const fileHandle = await root.getFileHandle(name, { create: true });
  const writable = await fileHandle.createWritable();
  await writable.write(text);
  await writable.close();
};

const loadNote = async (name) => {
  const root = await navigator.storage.getDirectory();
  const fileHandle = await root.getFileHandle(name);
  const file = await fileHandle.getFile();
  return file.text();
};

await saveNote('notiz.txt', 'Einkaufen: Milch, Brot');
console.log(await loadNote('notiz.txt'));
Einkaufen: Milch, Brot

Unterverzeichnis anlegen und Inhalt auflisten

const root = await navigator.storage.getDirectory();
const cacheDir = await root.getDirectoryHandle('bilder', { create: true });
await cacheDir.getFileHandle('logo.png', { create: true });
await cacheDir.getFileHandle('banner.png', { create: true });

for await (const [name, handle] of cacheDir.entries()) {
  console.log(`${handle.kind}: ${name}`);
}
file: banner.png file: logo.png

Schneller synchroner Zugriff im Dedicated Worker

// worker.js – nur in Dedicated Workern verfügbar
self.onmessage = async ({ data }) => {
  const root = await navigator.storage.getDirectory();
  const fileHandle = await root.getFileHandle('log.bin', { create: true });
  const access = await fileHandle.createSyncAccessHandle();

  const bytes = new TextEncoder().encode(data);
  const size = access.getSize();
  access.write(bytes, { at: size }); // anhängen
  access.flush();
  access.close();

  self.postMessage(`Neue Größe: ${size + bytes.byteLength} Bytes`);
};
Neue Größe: 12 Bytes

Unterstützung prüfen und OPFS leeren

const clearOpfs = async () => {
  if (!navigator.storage?.getDirectory) {
    console.warn('OPFS wird nicht unterstützt');
    return;
  }
  const root = await navigator.storage.getDirectory();
  for await (const name of root.keys()) {
    await root.removeEntry(name, { recursive: true });
  }
  console.log('OPFS geleert');
};

await clearOpfs();
OPFS geleert

// Wichtig · Fallstricke

  • Nur in sicherem Kontext: Die Methode ist nur über HTTPS oder localhost verfügbar. Sie funktioniert im Hauptthread und in Workern.
  • Kein Zugriff auf Nutzerdateien: Das OPFS ist vom echten Dateisystem getrennt. Für Dateien des Nutzers braucht man showOpenFilePicker() bzw. showDirectoryPicker(). Diese gibt es derzeit nur in Chromium-Browsern.
  • createSyncAccessHandle() gibt es nur in Dedicated Workern. Solange ein solches Handle offen ist, ist die Datei gesperrt. Deshalb immer close() aufrufen.
  • createWritable() wird in Safari erst ab Version 17.4 unterstützt. In älteren Safari-Versionen schreibt man über ein Sync-Access-Handle im Worker.
  • In privaten Fenstern ist das OPFS oft nur vorübergehend vorhanden oder gar nicht verfügbar (SecurityError). Den Aufruf deshalb in try...catch einbetten.
  • Die Daten zählen zum Kontingent der Herkunft (siehe navigator.storage.estimate()). Der Browser kann sie löschen, solange keine dauerhafte Speicherung (persist()) gewährt wurde. Löscht der Nutzer die Website-Daten, werden sie ebenfalls entfernt.
  • Die Reihenfolge beim Durchlaufen mit entries()/keys() ist nicht garantiert.