File System Access API 和 Origin Private File System API 都允许开发者访问用户设备上的文件和目录。前者允许开发者读取和写入常规的、用户可见的文件系统,而后者则会打开一个特殊的、对用户隐藏的文件系统,该文件系统专属于每个网站的来源,并具有一定的性能优势。在这两种情况下,开发者与文件和目录的互动都是通过 FileSystemHandle
对象进行的,更具体地说,对于文件,是通过 FileSystemFileHandle
对象进行的;对于目录,是通过 FileSystemDirectoryHandle
对象进行的。到目前为止,要了解任一文件系统中文件或目录的更改,都需要某种形式的轮询,并比较 lastModified
时间戳,甚至比较文件内容本身。
Chrome 129 中开始进行源试用的 File System Observer API 改变了这种情况,让开发者可以在发生更改时自动收到提醒。本指南介绍了该功能的运作方式以及如何试用该功能。
使用场景
在需要及时了解可能的文件系统更改的应用中使用 File System Observer API。
- 基于 Web 的集成开发环境 (IDE),可显示项目的文件系统树的表示形式。
- 将文件系统更改与服务器同步的应用。例如,SQLite 数据库文件。
- 需要从工作器或其他标签页向主线程通知文件系统更改的应用。
- 观察资源目录的应用,例如,自动优化图片的应用。
- 可从热重载中获益的体验,例如基于 HTML 的幻灯片演示,其中文件更改会触发重载。
如何使用 File System Observer API
功能检测
如需查看是否支持文件系统观察器 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
):changedHandle
相对于root
的路径。type
(String
):更改的类型。可能的值如下:"appeared"
:相应文件或目录已创建或移至root
。"disappeared"
:相应文件或目录已被删除或移出root
。"modified"
:文件或目录已修改。"moved"
:相应文件或目录已移至root
内。"unknown"
:这表示错过了零个或多个事件。开发者应轮询受监控的目录以响应此事件。"errored"
:观测结果已失效。在这种情况下,您可能需要停止观察文件系统。当每个来源的观测次数达到上限时,系统也会发送此值。此限制取决于操作系统,无法预先得知。如果发生这种情况,网站可能会决定重试,但无法保证操作系统已释放足够的资源。此值会在观察到的句柄(即观察的根)被删除或移动时发送。在这种情况下,系统会先发送"disappeared"
事件,然后发送"errored"
事件,表明相应观测结果不再有效。最后,当目录或文件句柄的权限被移除时,系统会发送此事件。
relativePathMovedFrom
(Array
,可选):已迁移的标识名的原位置。仅在type
为"moved"
时可用。
停止观测文件或目录
如需停止观测 FileSystemHandle
,请调用 unobserve()
方法,并将句柄作为实参传递给该方法。
observer.unobserve(fileHandle);
停止观察文件系统
如需停止观察文件系统,请按如下方式断开 FileSystemObserver
实例的连接。
observer.disconnect();
试用 API
如需在本地测试文件系统观察器 API,请在 about:flags
中设置 #file-system-observer
标志。如需通过真实用户测试该 API,请注册源试用,并按照 Chrome 源试用指南中的说明操作。源试用将从 Chrome 129(2024 年 9 月 11 日)开始,到 Chrome 134(2025 年 2 月 26 日)结束。
演示
您可以在嵌入式演示中查看文件系统观察器 API 的实际应用。查看源代码。该演示会随机创建、删除或修改受监控目录中的文件,并在应用窗口的上部记录其活动。然后,它会在应用窗口的下部记录发生的更改。如果您在不支持 File System Observer API 的浏览器中阅读本文,请参阅演示的屏幕截图。
反馈
如果您对文件系统观察器 API 的形状有反馈,请在 WHATWG/fs 仓库中针对问题 #123 发表评论。
相关链接
致谢
本文档由 Daseul Lee、Nathan Memmott、Etienne Noël 和 Rachel Andrew 审核。