Start · Sprachen · JavaScript · Referenz · FileSystemChangeRecord

FileSystemChangeRecord

Schnittstelle

Das Wörterbuch <code>FileSystemChangeRecord</code> beschreibt eine einzelne Änderung an Datei oder Verzeichnis, die ein <code>FileSystemObserver</code> festgestellt hat.

seit JavaScript Experimentell: Chrome/Edge 133+ (Chromium), nicht Kategorie: webapi

Signatur

interface FileSystemChangeRecord

Beschreibung

FileSystemChangeRecord ist ein Wörterbuch (Dictionary) der File System API. Man erzeugt es nie selbst: Der Browser übergibt ein Array solcher Einträge an die Callback-Funktion eines FileSystemObserver, sobald sich in einem beobachteten Bereich etwas ändert. Das kann das Origin Private File System (OPFS) sein oder ein Ordner bzw. eine Datei, den der Nutzer über showDirectoryPicker() bzw. showOpenFilePicker() freigegeben hat.

Jeder Eintrag sagt, was passiert ist (type), wo es passiert ist (changedHandle und relativePathComponents) und welche Beobachtung den Eintrag ausgelöst hat (root). Bei Verschiebungen oder Umbenennungen steht in relativePathMovedFrom zusätzlich der alte Pfad.

Typische Einsatzfälle sind Editoren und IDEs im Browser, die einen Projektordner synchron halten, Dateimanager, Werkzeuge mit automatischem Neuladen oder Synchronisierung zwischen Tabs oder Workern, die in dasselbe OPFS schreiben. Statt regelmäßig nachzufragen (Polling), wird die Anwendung gezielt benachrichtigt.

Mögliche Werte von type: "appeared" (neu angelegt oder hinzugekommen), "disappeared" (gelöscht), "modified" (Inhalt geändert), "moved" (verschoben oder umbenannt), "unknown" (Änderungen sind möglicherweise verloren gegangen, man sollte neu einlesen) und "errored" (die Beobachtung ist fehlgeschlagen und endet).

Parameter

Name Typ Default Beschreibung
$changedHandle Pflicht FileSystemFileHandle | FileSystemDirectoryHandle | FileSystemSyncAccessHandle | null Handle der geänderten Datei oder des geänderten Verzeichnisses. Im OPFS kann es auch ein FileSystemSyncAccessHandle sein. Bei "disappeared", "unknown" oder "errored" verweist es unter Umständen auf ein Element, das nicht mehr existiert.
$relativePathComponents Pflicht string[] Pfad der Änderung relativ zu root, als Array von Namen, z. B. ["src", "main.js"]. Ist der Wert leer, betrifft die Änderung root selbst.
$relativePathMovedFrom Pflicht string[] | null null Nur bei type === "moved" belegt: der frühere Pfad relativ zu root. Sonst null.
$root Pflicht FileSystemFileHandle | FileSystemDirectoryHandle | FileSystemSyncAccessHandle Das Handle, das an observer.observe() übergeben wurde. Damit lässt sich unterscheiden, welche von mehreren Beobachtungen den Eintrag ausgelöst hat.
$type Pflicht "appeared" | "disappeared" | "modified" | "moved" | "unknown" | "errored" Art der Änderung (siehe Beschreibung).

Rückgabewert

Typ
FileSystemChangeRecord
Beschreibung
Ein reines Datenobjekt mit schreibgeschützten Eigenschaften. Es wird als Element des records-Arrays an den Callback von FileSystemObserver übergeben.

Beispiele

Einträge im OPFS protokollieren

const root = await navigator.storage.getDirectory();

const observer = new FileSystemObserver((records, obs) => {
  for (const record of records) {
    const pfad = record.relativePathComponents.join('/') || '(root)';
    console.log(`${record.type}: ${pfad}`);
  }
});

await observer.observe(root, { recursive: true });

// Änderung auslösen
const datei = await root.getFileHandle('notizen.txt', { create: true });
const writable = await datei.createWritable();
await writable.write('Hallo');
await writable.close();
appeared: notizen.txt modified: notizen.txt

Umbenennungen und Verschiebungen auswerten

const handleRecord = (record) => {
  const pfad = record.relativePathComponents.join('/');
  switch (record.type) {
    case 'moved': {
      const alt = record.relativePathMovedFrom?.join('/') ?? '?';
      console.log(`Verschoben: ${alt} → ${pfad}`);
      break;
    }
    case 'disappeared':
      console.log(`Gelöscht: ${pfad}`);
      break;
    case 'appeared':
    case 'modified':
      console.log(`${record.type}: ${pfad} (${record.changedHandle?.kind})`);
      break;
  }
};

const observer = new FileSystemObserver((records) => records.forEach(handleRecord));
const dir = await navigator.storage.getDirectory();
await observer.observe(dir, { recursive: true });

const f = await dir.getFileHandle('entwurf.md', { create: true });
await f.move('final.md');
appeared: entwurf.md (file) Verschoben: entwurf.md → final.md

Projektordner eines Editors synchron halten (inkl. unknown/errored)

const button = document.querySelector('#ordner-oeffnen');

button.addEventListener('click', async () => {
  const projekt = await window.showDirectoryPicker();

  const neuEinlesen = async () => {
    const namen = [];
    for await (const [name] of projekt.entries()) namen.push(name);
    console.log('Dateiliste aktualisiert:', namen);
  };

  const observer = new FileSystemObserver(async (records, obs) => {
    for (const record of records) {
      if (record.type === 'errored') {
        console.warn('Beobachtung beendet für', record.root.name);
        obs.disconnect();
        return;
      }
      if (record.type === 'unknown') {
        // Änderungen sind evtl. verloren gegangen – komplett neu einlesen
        await neuEinlesen();
        return;
      }
    }
    await neuEinlesen();
  });

  await observer.observe(projekt, { recursive: true });
  await neuEinlesen();
});
Dateiliste aktualisiert: ["index.html", "src", "package.json"]

// Wichtig · Fallstricke

  • Experimentell: FileSystemObserver und damit FileSystemChangeRecord gibt es bisher nur in Chromium-Browsern (Chrome/Edge ab etwa Version 133). Firefox und Safari unterstützen sie nicht. Vor der Nutzung prüfen: if ('FileSystemObserver' in self) { … }.
  • Die Reihenfolge und Zusammenfassung der Einträge ist nicht garantiert. Ein Speichervorgang kann mehrere "modified"-Einträge erzeugen, eine Umbenennung auf manchen Plattformen als "disappeared" und anschließend "appeared" erscheinen statt als "moved".
  • Bei "unknown" sollte man den Zustand vollständig neu einlesen, statt sich auf einzelne Einträge zu verlassen.
  • Nach "errored" kommen für diese Beobachtung keine Meldungen mehr, sie muss mit observe() neu gestartet werden, z. B. wenn der Nutzer die Berechtigung entzogen hat.
  • changedHandle kann auf eine gelöschte Datei zeigen. Zugriffe wie getFile() werfen dann einen NotFoundError und sollten mit try/catch abgesichert werden.
  • Nur in sicheren Kontexten (HTTPS) verfügbar. Außerhalb des OPFS ist zusätzlich eine Lese-Berechtigung für das beobachtete Handle nötig.