File System Access API と Origin Private File System API のどちらも、デベロッパーがユーザーのデバイス上のファイルとディレクトリにアクセスできるようにします。前者は、デベロッパーが通常のユーザーに表示されるファイル システムに対して読み取りと書き込みを行うことができます。後者は、各サイトのオリジンに固有の、ユーザーには非表示の特別なファイル システムを開き、特定のパフォーマンス上の利点があります。どちらの場合も、デベロッパーがファイルとディレクトリを操作する方法は、FileSystemHandle
オブジェクトです。具体的には、ファイルの場合は FileSystemFileHandle
、ディレクトリの場合は FileSystemDirectoryHandle
です。これまで、どちらのファイル システムでもファイルまたはディレクトリの変更を通知するには、なんらかのポーリングと lastModified
タイムスタンプ、またはファイルの内容自体の比較が必要でした。
Chrome 129 のオリジン トライアルで導入された File System Observer API では、この点が変更され、変更が発生したときにデベロッパーに自動的にアラートが表示されます。このガイドでは、この機能の仕組みと試す方法について説明します。
ユースケース
ファイル システムの変更が発生した直後に通知する必要があるアプリでは、File System Observer API を使用します。
- プロジェクトのファイル システム ツリーを表示するウェブベースの統合開発環境(IDE)。
- ファイルシステムの変更をサーバーと同期するアプリ。たとえば、SQLite データベース ファイルです。
- ワーカーまたは別のタブからファイル システムの変更をメインスレッドに通知する必要があるアプリ。
- 画像を自動的に最適化するためにリソースのディレクトリを監視するアプリなど。
- ホットリロードのメリットがあるエクスペリエンス(ファイルの変更によって再読み込みがトリガーされる HTML ベースのスライド デッキなど)。
File System Observer API の使用方法
特徴検出
File System Observer API がサポートされているかどうかを確認するには、次の例のように機能テストを実行します。
if ('FileSystemObserver' in self) {
// The File System Observer API is supported.
}
ファイル システム オブザーバーを初期化する
new FileSystemObserver()
を呼び出して、callback
関数を引数として渡し、ファイル システム オブザーバーを初期化します。
const observer = new FileSystemObserver(callback);
ファイルまたはディレクトリのモニタリングを開始する
ファイルまたはディレクトリの監視を開始するには、FileSystemObserver
インスタンスの非同期 observe()
メソッドを呼び出します。このメソッドには、選択したファイルまたはディレクトリの FileSystemHandle
を引数として指定します。ディレクトリを監視するときに、オプションの options
引数を使用して、ディレクトリの変更(ディレクトリ自体と、そこに含まれるサブディレクトリとファイルのすべて)を再帰的に通知するかどうかを選択できます。デフォルトでは、ディレクトリ自体と直接含まれているファイルのみをモニタリングします。
// Observe a file.
await observer.observe(fileHandle);
// Observe a directory.
await observer.observe(directoryHandle);
// Observe a directory recursively.
await observer.observe(directoryHandle, {recursive: true});
コールバック関数
ファイル システムに変更があると、ファイル システムの変更 records
と observer
自体を引数としてコールバック関数が呼び出されます。observer
引数を使用すると、たとえば、関心のあるファイルがすべて削除されたときにオブザーバーを切断できます(ファイル システムの監視を停止するを参照)。
const callback = (records, observer) => {
for (const record of records) {
console.log('Change detected', record);
}
};
ファイル システム変更レコード
各ファイル システム変更レコードの構造は次のとおりです。すべてのフィールドは読み取り専用です。
root
(FileSystemHandle
):FileSystemObserver.observe()
関数に渡されるハンドル。changedHandle
(FileSystemHandle
): ファイル システムの変更の影響を受けるハンドル。このフィールドは、"errored"
、"unknown"
、"disappeared"
タイプのイベントではnull
になります。消失したファイルまたはディレクトリを確認するには、relativePathComponents
を使用します。relativePathComponents
(Array
):root
を基準としたchangedHandle
のパス。type
(String
): 変更のタイプ。次のタイプを使用できます。"appeared"
: ファイルまたはディレクトリが作成されたか、root
に移動されました。"disappeared"
: ファイルまたはディレクトリが削除されたか、root
から移動されました。"modified"
: ファイルまたはディレクトリが変更されました。"moved"
: ファイルまたはディレクトリがroot
内で移動されました。"unknown"
: 0 個以上のイベントが検出されなかったことを示します。デベロッパーは、これに応じて監視対象ディレクトリをポーリングする必要があります。"errored"
: 観測が無効になりました。この場合は、ファイル システムの監視を停止することをおすすめします。この値は、オリジンごとの観測の最大上限に達した場合にも送信されます。この上限はオペレーティング システムによって異なり、事前に把握することはできません。この場合、サイトは再試行を決定することがあります。ただし、オペレーティング システムが十分なリソースを解放するとは限りません。この値が送信されるもう 1 つのケースは、観測されたハンドル(観測のルート)が削除または移動された場合です。この場合、まず"disappeared"
イベントが送信され、その後に"errored"
イベントが送信されます。これは、観測が有効でなくなったことを示します。最後に、このイベントは、ディレクトリまたはファイル ハンドルに対する権限が削除されたときに送信されます。
relativePathMovedFrom
(Array
、省略可): 移動されたハンドルの以前の位置。type
が"moved"
の場合にのみ使用できます。
ファイルまたはディレクトリの監視を停止する
FileSystemHandle
の監視を停止するには、unobserve()
メソッドを呼び出して、ハンドルを引数として渡します。
observer.unobserve(fileHandle);
ファイル システムのモニタリングを停止する
ファイル システムの監視を停止するには、次のように FileSystemObserver
インスタンスを切断します。
observer.disconnect();
API を試す
File System Observer API をローカルでテストするには、about:flags
で #file-system-observer
フラグを設定します。実際のユーザーで API をテストするには、オリジン トライアルに登録し、Chrome オリジン トライアルのガイドに沿って手順に沿って操作します。オリジン トライアルは、Chrome 129(2024 年 9 月 11 日)から Chrome 134(2025 年 2 月 26 日)まで実施されます。
デモ
File System Observer API の動作は、埋め込まれたデモで確認できます。ソースコードを確認するか、Glitch でデモコードをリミックスしてください。このデモでは、監視対象のディレクトリ内のファイルをランダムに作成、削除、変更し、そのアクティビティをアプリ ウィンドウの上部に記録します。変更が発生すると、アプリ ウィンドウの下部にログが記録されます。File System Observer API をサポートしていないブラウザでこの記事を読んでいる場合は、デモのスクリーンショットをご覧ください。
フィードバック
File System Observer API の形状についてフィードバックがある場合は、WHATWG/fs リポジトリの Issue #123 にコメントしてください。
関連リンク
謝辞
このドキュメントは、Daseul Lee、Nathan Memmott、Etienne Noël、Rachel Andrew が確認しました。