The
origin private file system
provides access to a special kind of file that is highly optimized for performance, for example, by
offering in-place and exclusive write access to a file's content. Developers can get access to such
files by calling
createSyncAccessHandle()
,
which is a method exposed on
FileSystemFileHandle
objects. This call
results in a FileSystemSyncAccessHandle
.
FileSystemSyncAccessHandle
is a file primitive that provides performant access to local files. One
of its main use cases is applications porting C/C++ code to Wasm; however, asynchronous calls are
not fully supported on Wasm yet, and using the
Asyncify library as an alternative has
substantially degraded performance. Making all the methods of the FileSystemSyncAccessHandle
synchronous matches the synchronous, POSIX-like file API Wasm-based application expect; making the API more ergonomic while bringing substantial performance gains.
What's new?
FileSystemSyncAccessHandle
exposes the following methods that used to be asynchronous, but that
are synchronous as of Chromium 108.
truncate(newSize)
: Resizes the file associated with the access handle to benewSize
bytes long. IfnewSize
is larger than the current file size, it pads the file with null bytes; otherwise it truncates the file.getSize()
: Returns the size of the file associated with the access handle in bytes.flush()
: Ensures that the contents of the file associated with the access handle contain all the modifications done throughwrite()
.close()
: Flushes the access handle and then closes it. Closing an access handle disables any further operations on it and releases the lock on the entry associated with the access handle.
// 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();
What do I need to do?
Note that changing methods from asynchronous to synchronous is a web-exposed change with potential
breakage. While using await
in synchronous methods is a no-op, any use of Promise.then()
will break.
If you chain a then()
call on the result of any of the previously asynchronous and now
synchronous methods, you need to change your code.
// (✅) 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 */
Related links
- TAG Review
- Specification
- Specification Issue (which led to the change)
- ChromeStatus entry
- Chromium bug