互換性を破る変更: AccessHandles の同期メソッド

送信元のプライベート ファイル システムは、ファイルのコンテンツへのインプレース書き込みアクセスや排他的書き込みアクセスなど、パフォーマンスを重視して高度に最適化された特別な種類のファイルへのアクセスを提供します。デベロッパーは、FileSystemFileHandle オブジェクトで公開されているメソッドである createSyncAccessHandle() を呼び出すことで、このようなファイルにアクセスできます。この呼び出しの結果は FileSystemSyncAccessHandle です。

FileSystemSyncAccessHandle は、ローカル ファイルへの高パフォーマンスなアクセスを提供するファイル プリミティブです。主なユースケースの 1 つは、C/C++ コードを Wasm に移植するアプリケーションです。ただし、非同期呼び出しは Wasm ではまだ完全にサポートされておらず、代わりに Asyncify ライブラリを使用するとパフォーマンスが大幅に低下します。FileSystemSyncAccessHandle のすべてのメソッドを同期化することで、Wasm ベースのアプリケーションが期待する POSIX ライクな同期ファイル API と一致し、API の使い勝手が向上し、パフォーマンスが大幅に向上します。

最新情報

FileSystemSyncAccessHandle は、以前は非同期だったが、Chromium 108 以降は同期である次のメソッドを公開します。

  • truncate(newSize): アクセス ハンドルに関連付けられたファイルのサイズを newSize バイトに変更します。newSize が現在のファイルサイズより大きい場合は、ファイルに null バイトを追加します。それ以外の場合は、ファイルが切り捨てられます。
  • getSize(): アクセス ハンドルに関連付けられたファイルのサイズをバイト単位で返します。
  • flush(): アクセス ハンドルに関連付けられたファイルの内容に、write() を介して行われたすべての変更が含まれていることを確認します。
  • close(): アクセス ハンドルをフラッシュしてからクローズします。アクセス ハンドルを閉じると、そのハンドルに対するそれ以降の操作が無効になり、アクセス ハンドルに関連付けられているエントリのロックが解除されます。
// 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();

必要なご対応

メソッドを非同期から同期に変更することは、ウェブに公開される変更であり、破損する可能性があります。同期メソッドで await を使用することは無効ですが、Promise.then() を使用すると破損します。以前は非同期で、現在は同期のメソッドの結果に対して then() 呼び出しを連結している場合は、コードを変更する必要があります。

// (✅) 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 */