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

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

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