File System API

Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.

Hinweis: Diese Funktion ist in Web Workers verfügbar.

Die Dateisystem-API — mit Erweiterungen, die über die Dateisystem-Zugriffs-API bereitgestellt werden, um auf Dateien im Dateisystem des Geräts zuzugreifen — ermöglicht Lese-, Schreib- und Dateiverwaltungsfunktionen.

Sehen Sie sich den Abschnitt Beziehung zu anderen dateibezogenen APIs an, um einen Vergleich zwischen dieser API, der Datei- und Verzeichniseintrags-API und der Datei-API zu erhalten.

Konzepte und Nutzung

Diese API ermöglicht die Interaktion mit Dateien auf einem lokalen Gerät des Benutzers oder auf einem vom Benutzer zugänglichen Netzwerk-Dateisystem. Die Kernfunktionalität dieser API umfasst das Lesen von Dateien, das Schreiben oder Speichern von Dateien und den Zugriff auf die Verzeichnisstruktur.

Die meiste Interaktion mit Dateien und Verzeichnissen erfolgt über „Handles“. Eine übergeordnete Klasse FileSystemHandle hilft dabei, zwei untergeordnete Klassen zu definieren: FileSystemFileHandle und FileSystemDirectoryHandle, jeweils für Dateien und Verzeichnisse.

Die Handles repräsentieren eine Datei oder ein Verzeichnis auf dem System des Benutzers. Sie können zuerst Zugriff auf sie erhalten, indem Sie dem Benutzer eine Dateiauswahl oder Verzeichnisauswahl mit Methoden wie window.showOpenFilePicker() und window.showDirectoryPicker() anzeigen. Sobald diese aufgerufen werden, erscheint der Dateiauswahldialog und der Benutzer wählt entweder eine Datei oder ein Verzeichnis. Sobald dies erfolgreich geschieht, wird ein Handle zurückgegeben.

Sie können über folgende Methoden auch Zugriff auf Datei-Handles erhalten:

Jedes Handle bietet seine eigene Funktionalität und es gibt einige Unterschiede, abhängig davon, welches Sie verwenden (siehe den Abschnitt Schnittstellen für spezifische Details). Sie können dann auf Datei-Daten oder Informationen (einschließlich Kinder) des ausgewählten Verzeichnisses zugreifen. Diese API eröffnet potenzielle Funktionalitäten, die dem Web fehlten. Dennoch war die Sicherheit beim Design der API von größter Bedeutung, und der Zugriff auf Datei-/Verzeichnisdaten ist untersagt, es sei denn, der Benutzer erteilt ausdrücklich die Erlaubnis (beachten Sie, dass dies nicht für das origin-privates Dateisystem gilt, da es für den Benutzer nicht sichtbar ist).

Hinweis: Die verschiedenen Ausnahmen, die beim Verwenden der Funktionen dieser API ausgelöst werden können, sind auf den relevanten Seiten aufgeführt, wie in der Spezifikation definiert. Allerdings wird die Situation durch die Interaktion der API mit dem zugrunde liegenden Betriebssystem komplizierter. Ein Vorschlag wurde gemacht, um die Fehlerzuordnungen in der Spezifikation aufzulisten, der nützliche verwandte Informationen enthält.

Hinweis: Objekte, die auf FileSystemHandle basieren, können auch in einer IndexedDB-Datenbankinstanz serialisiert oder über postMessage() übertragen werden.

Origin-privates Dateisystem

Das origin-private Dateisystem (OPFS) ist ein Speicher-Endpunkt, der als Teil der Dateisystem-API bereitgestellt wird. Es ist privat für den Ursprung der Seite und für den Benutzer nicht sichtbar, wie das reguläre Dateisystem. Es bietet Zugriff auf eine besondere Art von Datei, die hochgradig für Leistung optimiert ist und in-place Schreibzugriff auf deren Inhalt bietet.

Die folgenden sind einige mögliche Anwendungsfälle:

  • Apps mit persistentem Uploader

    • Wenn eine Datei oder ein Verzeichnis zum Hochladen ausgewählt wird, können Sie die Datei in eine lokale Sandbox kopieren und Stück für Stück hochladen.
    • Die App kann Uploads nach einer Unterbrechung neu starten, wie z.B. wenn der Browser geschlossen wird oder abstürzt, die Verbindung unterbrochen wird oder der Computer heruntergefahren wird.
  • Videospiel oder andere Apps mit vielen Medieninhalten

    • Die App lädt ein oder mehrere große Tarballs herunter und entpackt sie lokal in eine Verzeichnisstruktur.
    • Die App holt Assets im Hintergrund vor, sodass der Benutzer zur nächsten Aufgabe oder Spielstufe wechseln kann, ohne auf einen Download zu warten.
  • Audio- oder Bildbearbeitungsprogramm mit Offline-Zugriff oder lokalem Cache (ideal für Leistung und Geschwindigkeit)

    • Die App kann Dateien vor Ort überschreiben (beispielsweise nur die ID3/EXIF-Tags und nicht die gesamte Datei überschreiben).
  • Offline-Video-Viewer

    • Die App kann große Dateien (>1GB) für spätere Betrachtung herunterladen.
    • Die App kann auf teilweise heruntergeladene Dateien zugreifen (damit Sie das erste Kapitel Ihrer DVD anschauen können, auch wenn die App noch den Rest des Inhalts herunterlädt oder wenn die App den Download nicht abgeschlossen hat, weil Sie einen Zug erreichen mussten).
  • Offline-Webmail-Client

    • Der Client lädt Anhänge herunter und speichert sie lokal.
    • Der Client zwischenspeichert Anhänge für einen späteren Upload.

Lesen Sie unsere Origin-private Dateisystem für Anleitungen zur Verwendung.

Dateien speichern

  • Bei den asynchronen Handles verwenden Sie die FileSystemWritableFileStream-Schnittstelle. Sobald die Daten, die Sie speichern möchten, in ein Format von Blob, String-Objekt, String-Literal oder Buffer vorliegen, können Sie einen Stream öffnen und die Daten in einer Datei speichern. Dies kann die vorhandene oder eine neue Datei sein.
  • Im Fall der synchronen FileSystemSyncAccessHandle bearbeiten Sie Änderungen an einer Datei über die write()-Methode. Sie können optional auch flush() aufrufen, wenn Sie die Änderungen zu einem bestimmten Zeitpunkt auf die Festplatte speichern müssen (ansonsten können Sie das zugrunde liegende Betriebssystem dies handhaben lassen, wenn es dies für angemessen hält, was in den meisten Fällen in Ordnung sein sollte).

Schnittstellen

FileSystemChangeRecord Experimentell

Enthält Details zu einer einzelnen Änderung, die von einem FileSystemObserver beobachtet wird.

FileSystemHandle

Ein Objekt, das einen Datei- oder Verzeichniseintrag repräsentiert. Mehrere Handles können denselben Eintrag repräsentieren. Meistens arbeiten Sie nicht direkt mit FileSystemHandle, sondern mit seinen Kinderschnittstellen FileSystemFileHandle und FileSystemDirectoryHandle.

FileSystemFileHandle

Bietet einen Handle zu einem Dateisystemeintrag.

FileSystemDirectoryHandle

Bietet einen Handle zu einem Dateisystemverzeichnis.

FileSystemObserver Experimentell

Bietet einen Mechanismus, um Änderungen an ausgewählten Dateien oder Verzeichnissen zu beobachten.

FileSystemSyncAccessHandle

Bietet einen synchronen Handle zu einem Dateisystemeintrag, der in-place auf einer einzigen Datei auf der Festplatte arbeitet. Die synchrone Natur der Datei-Lese- und Schreiboperationen ermöglicht eine höhere Leistung für kritische Methoden in Kontexten, in denen asynchrone Operationen mit hohen Overhead verbunden sind, z.B. WebAssembly. Diese Klasse ist nur innerhalb dedizierter Web Worker für Dateien im origin-privaten Dateisystem zugänglich.

FileSystemWritableFileStream

Ein WritableStream-Objekt mit zusätzlichen Komfortmethoden, das auf einer einzigen Datei auf der Festplatte arbeitet.

Erweiterungen zu anderen Schnittstellen

Window.showDirectoryPicker()

Zeigt eine Verzeichnisauswahl an, die es dem Benutzer ermöglicht, ein Verzeichnis auszuwählen.

Window.showOpenFilePicker()

Zeigt eine Dateiauswahl an, die es einem Benutzer ermöglicht, eine oder mehrere Dateien auszuwählen.

Window.showSaveFilePicker()

Zeigt eine Dateiauswahl an, die es einem Benutzer ermöglicht, eine Datei zu speichern.

DataTransferItem.getAsFileSystemHandle()

Gibt ein Promise zurück, das mit einem FileSystemFileHandle erfüllt wird, wenn das gezogene Element eine Datei ist, oder mit einem FileSystemDirectoryHandle, wenn das gezogene Element ein Verzeichnis ist.

StorageManager.getDirectory()

Wird verwendet, um eine Referenz zu einem FileSystemDirectoryHandle-Objekt zu erhalten, das Zugriff auf ein Verzeichnis und dessen Inhalte ermöglicht, die im origin-privaten Dateisystem gespeichert sind. Gibt ein Promise zurück, das mit einem FileSystemDirectoryHandle-Objekt erfüllt wird.

Beispiele

Zugriff auf Dateien

Der unten stehende Code erlaubt es dem Benutzer, eine Datei aus dem Dateiauswahldialog auszuwählen.

js
async function getFile() {
  // Open file picker and destructure the result the first handle
  const [fileHandle] = await window.showOpenFilePicker();
  const file = await fileHandle.getFile();
  return file;
}

Die folgende asynchrone Funktion präsentiert einen Dateiauswahl-Dialog und verwendet, sobald eine Datei ausgewählt wurde, die getFile()-Methode, um den Inhalt abzurufen.

js
const pickerOpts = {
  types: [
    {
      description: "Images",
      accept: {
        "image/*": [".png", ".gif", ".jpeg", ".jpg"],
      },
    },
  ],
  excludeAcceptAllOption: true,
  multiple: false,
};

async function getTheFile() {
  // Open file picker and destructure the result the first handle
  const [fileHandle] = await window.showOpenFilePicker(pickerOpts);

  // get file contents
  const fileData = await fileHandle.getFile();
}

Zugriff auf Verzeichnisse

Das folgende Beispiel gibt einen Verzeichnishandle mit dem angegebenen Namen zurück. Wenn das Verzeichnis nicht existiert, wird es erstellt.

js
const dirName = "directoryToGetName";

// assuming we have a directory handle: 'currentDirHandle'
const subDir = currentDirHandle.getDirectoryHandle(dirName, { create: true });

Die folgende asynchrone Funktion verwendet resolve(), um den Pfad zu einer ausgewählten Datei relativ zu einem angegebenen Verzeichnishandle zu finden.

js
async function returnPathDirectories(directoryHandle) {
  // Get a file handle by showing a file picker:
  const [handle] = await self.showOpenFilePicker();
  if (!handle) {
    // User cancelled, or otherwise failed to open a file.
    return;
  }

  // Check if handle exists inside our directory handle
  const relativePaths = await directoryHandle.resolve(handle);

  if (relativePaths === null) {
    // Not inside directory handle
  } else {
    // relativePaths is an array of names, giving the relative path

    for (const name of relativePaths) {
      // log each entry
      console.log(name);
    }
  }
}

Schreiben in Dateien

Die folgende asynchrone Funktion öffnet den Dateispeicherdialog, der ein FileSystemFileHandle zurückgibt, sobald eine Datei ausgewählt ist. Ein schreibbarer Stream wird dann mittels der Methode FileSystemFileHandle.createWritable() erstellt.

Ein benutzerdefinierter Blob wird dann in den Stream geschrieben, der anschließend geschlossen wird.

js
async function saveFile() {
  // create a new handle
  const newHandle = await window.showSaveFilePicker();

  // create a FileSystemWritableFileStream to write to
  const writableStream = await newHandle.createWritable();

  // write our file
  await writableStream.write(imgBlob);

  // close the file and write the contents to disk.
  await writableStream.close();
}

Die folgenden Beispiele zeigen verschiedene Optionen, die in die write()-Methode übergeben werden können.

js
// just pass in the data (no options)
writableStream.write(data);

// writes the data to the stream from the determined position
writableStream.write({ type: "write", position, data });

// updates the current file cursor offset to the position specified
writableStream.write({ type: "seek", position });

// resizes the file to be size bytes long
writableStream.write({ type: "truncate", size });

Synchrones Lesen und Schreiben von Dateien in OPFS

Dieses Beispiel liest und schreibt synchron eine Datei in das origin-private Dateisystem.

Die folgende asynchrone Ereignisbehandlungsfunktion ist in einem Web Worker enthalten. Beim Empfang einer Nachricht vom Hauptthread:

  • Erstellt sie einen synchronen Datei-Zugriffshandle.
  • Erfasst die Größe der Datei und erstellt einen ArrayBuffer, um diese zu enthalten.
  • Liest die Dateiinhalte in den Puffer.
  • Kodiert die Nachricht und schreibt sie ans Ende der Datei.
  • Speichert die Änderungen auf der Festplatte und schließt den Zugriffshandle.
js
onmessage = async (e) => {
  // retrieve message sent to work from main script
  const message = e.data;

  // Get handle to draft file in OPFS
  const root = await navigator.storage.getDirectory();
  const draftHandle = await root.getFileHandle("draft.txt", { create: true });
  // Get sync access handle
  const accessHandle = await draftHandle.createSyncAccessHandle();

  // Get size of the file.
  const fileSize = accessHandle.getSize();
  // Read file content to a buffer.
  const buffer = new DataView(new ArrayBuffer(fileSize));
  const readBuffer = accessHandle.read(buffer, { at: 0 });

  // Write the message to the end of the file.
  const encoder = new TextEncoder();
  const encodedMessage = encoder.encode(message);
  const writeBuffer = accessHandle.write(encodedMessage, { at: readBuffer });

  // Persist changes to disk.
  accessHandle.flush();

  // Always close FileSystemSyncAccessHandle if done.
  accessHandle.close();
};

Hinweis: In früheren Versionen der Spezifikation wurden close(), flush(), getSize() und truncate() unergonomisch als asynchrone Methoden spezifiziert. Dies wurde nun geändert, aber einige Browser unterstützen noch die asynchronen Versionen.

Spezifikationen

Specification
File System
File System Access

Browser-Kompatibilität

api.FileSystemHandle

api.FileSystemFileHandle

api.FileSystemDirectoryHandle

api.FileSystemWritableFileStream

api.FileSystemSyncAccessHandle

Siehe auch