Nicht abwärtskompatible Änderung: Synchronisierungsmethoden für AccessHandles

Das private Ursprungsdateisystem bietet Zugriff auf eine spezielle Art von Datei, die stark für die Leistung optimiert ist. Es bietet beispielsweise direkten und exklusiven Schreibzugriff auf den Inhalt einer Datei. Entwickler können Zugriff auf solche Dateien erhalten, indem sie createSyncAccessHandle() aufrufen. Dies ist eine Methode, die für FileSystemFileHandle-Objekte verfügbar gemacht wird. Dieser Aufruf führt zu einem FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle ist eine primitive Datei, die einen leistungsfähigen Zugriff auf lokale Dateien bietet. Einer der Hauptanwendungsfälle sind Anwendungen, die C/C++-Code auf Wasm portieren. Asynchrone Aufrufe werden auf Wasm jedoch noch nicht vollständig unterstützt und die Verwendung der Asyncify-Bibliothek als Alternative hat eine erhebliche Leistungseinbußen zur Folge. Da alle Methoden der FileSystemSyncAccessHandle synchron an die synchrone, POSIX-ähnliche Datei-API Wasm-basierte Anwendung angepasst werden, wird die API ergonomischer und die Leistung erheblich gesteigert.

Das ist neu

FileSystemSyncAccessHandle stellt die folgenden Methoden bereit, die früher asynchron waren, aber ab Chromium 108 synchron sind.

  • truncate(newSize): Ändert die Größe der mit dem Zugriffs-Handle verknüpften Datei auf newSize Byte. Wenn newSize größer als die aktuelle Dateigröße ist, wird die Datei mit null Byte aufgefüllt. Andernfalls wird die Datei gekürzt.
  • getSize(): Gibt die Größe der Datei, die mit dem Zugriffs-Handle verknüpft ist, in Byte zurück.
  • flush(): Dadurch wird sichergestellt, dass der Inhalt der Datei, die mit dem Zugriffs-Handle verknüpft ist, alle Änderungen enthält, die über write() vorgenommen wurden.
  • close(): Löscht den Zugriffs-Handle und schließt ihn dann. Durch das Schließen eines Zugriffs-Handles werden alle weiteren Vorgänge deaktiviert und die Sperre für den Eintrag aufgehoben, der mit dem Zugriffs-Handle verknüpft ist.
// In a `Worker`:
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('test', { create: true });
// `createSyncAccessHandle()` is still async.
const accessHandle = await fileHandle.createSyncAccessHandle();
// Both `read()` and `write()` were sync before.
accessHandle.read(/* ... */);
accessHandle.write(/* ... */);

// New: synchronous as of Chromium 108.
console.log(accessHandle.getSize());
accessHandle.truncate(123);
accessHandle.flush();
accessHandle.close();

Was muss ich tun?

Die Änderung von Methoden von einer asynchronen zu einer synchronen Methode ist eine durch das Web ausgesetzte Änderung, die zu Fehlern führen kann. Wenn await in synchronen Methoden verkehrslos verwendet wird, schlägt die Verwendung von Promise.then() fehl. Wenn Sie einen then()-Aufruf für das Ergebnis einer der zuvor asynchronen und jetzt synchronen Methoden verketten, müssen Sie Ihren Code ändern.

// (✅) This won't break, but you better remove the superfluous `await`:
await accessHandle.flush();
// ✅ Correct:
accessHandle.flush();
// ⛔️ This will break, and you need to restructure your code:
accessHandle.flush().then(/* Follow-up code */);
// ✅ Correct:
accessHandle.flush();
/* Follow-up code */