跳转到正文

存储与文件生命周期 ​

Weblink 将文件内容与引用它的消息、文件库条目和传输任务分开。统一的存储接口覆盖浏览器存储与真实目录,各提供方再实现适合自身平台的数据提交方式。

同一接口,不同存储提供方 ​

VfsVolume 描述平台卷操作。面向应用的存储服务通过 ChunkCache 提供文件:调用方可以读取数据、提交分块、查询续传范围、校验内容、完成写入和释放引用,无需解析物理路径。

提供方默认或选择方式主要边界
IndexedDB浏览器默认使用字节与事务元数据属于当前站点的浏览器存储
浏览器目录通过浏览器目录选择器指定取决于 API 支持、安全上下文、用户同意,有时需要重新授权
原生目录桌面端默认使用应用本地数据下的 files 目录,也可另选目录由桌面平台适配层执行文件系统操作

修改默认位置,只选择新内容的写入位置;已有文件和正在传输的任务保留原挂载点。浏览器目录不可用时,应用不会悄悄将其中的已有文件改写到另一种存储。

身份密钥、配对、权限和聊天记录属于独立的应用数据。选择文件目录,不会把这些记录搬进该目录。

目录扫描与导入内容 ​

挂载的目录会递归扫描。已有文件无需复制到另一份文件库就能出现,目录条目反映其挂载点、相对路径和修订状态;显式导入文件则会在选定存储中创建内容快照。

这个区别会影响外部程序修改文件后的处理:扫描到的来源可以变化或消失,已保存的内容引用不能把旧摘要当成新字节的证明。扫描失败或目录权限丢失时,系统保留上次已知的成员信息,不会把所有暂时无法访问的文件当成已删除。

文件元数据声明打开、定位文件等可用操作。界面请求存储服务执行操作,无需直接使用原生路径。共享文件列表通过设备协议提供已授权的元数据;挂载目录本身不会公开路径或共享其中的文件。

可恢复的未完成文件 ​

存储先提交数据字节,再提交分块检查点。重开未完成文件后,验证已提交分块摘要并请求缺失分块;所有分块通过完整内容验证后才能发布,校验或发布失败仍保留未完成数据。

左侧展示正常完成流程,虚线展示中断后的恢复。只有经过检查点验证的字节才计入续传,预分配文件长度不代表下载进度。

目录接收任务从 report.pdf.part 这样的未完成文件开始。系统先预留逻辑数据长度,再把收到的分块写到 chunkIndex * chunkSize。因此,看起来很大的文件尺寸不能证明数据已经到齐,也不保证物理磁盘空间已被实际预留。

未完成文件同时保存数据与恢复信息:

部分用途
数据区原文件字节位置,包括尚未接收的范围
分块检查点表记录已提交分块及其 BLAKE3 摘要
两个带校验的元数据槽保存传输元数据及预期最终路径,更新中断时可回退到之前有效的槽
带校验的尾部标识未完成文件格式、数据长度与分块大小

目录后端不需要旁路文件或独立的 IndexedDB 检查点记录,就能重建进度。IndexedDB 提供方则将自己的事务元数据和文件数据保存在同一后端内。

数据写入先于对应检查点提交。崩溃后,没有已提交检查点的字节会重新请求。重开未完成文件时,会检查已提交分块的摘要与实际字节是否一致,也正确处理内容恰好全为零的分块。元数据无效会使文件不可用,而不会将预分配空间误认为下载进度。

清除应用元数据不会擦除真实目录中的字节或文件内的恢复信息。目录仍需要重新挂载和授权;继续传输也仍需要可用来源及匹配的文件元数据。

完成不只是重命名 ​

所有分块到齐后,如果提供了预期内容指纹,存储服务还需要验证它。通过后才能发布完整内容,并移除未完成文件尾部和临时名称。

原生目录会在不替换已有目标的前提下移动文件,再截去尾部。浏览器目录则流式复制到最终文件,验证提交后的副本,最后移除临时文件。因此,浏览器完成这一步时需要同时容纳两份文件;发布失败仍会保留可恢复的未完成数据。

文件名分配也会保护已有文件。预期名称已被占用时,会选择另一个可用名称。长时间传输期间出现的同名文件,不会因此获得被覆盖的许可。

同一挂载点、路径和修订状态下的完整内容校验结果可以在内存中复用。应用重启或外部编辑后,需要重新验证;新复制出来的目标也单独检查。已保存或由对端提供的指纹始终是比较目标,不是本地完整性的缓存证明。

引用、使用租约与删除 ​

存储生命周期区分三类操作:

操作含义
释放引用停止为某个附件、文件库条目或操作保留内容
持有活动租约在传输或其他操作准备、使用内容期间保护它
显式删除来源检查来源版本仍匹配后,删除选中的存储文件

释放附件、内容去重或后台清理,不能删除用户拥有的完整来源文件。暂停或失败的传输可以保留已提交数据,用于恢复。权限错误或迁移失败也不构成删除数据的授权。

录制和其他生成文件使用带有界写入队列的流式写入器。停止生产数据与发布最终文件是两个步骤:必须排空待写数据并完成元数据,文件才算完成。设置面板是否关闭,不决定写入器的生命周期。

存储迁移遵循同样的归属原则:复制并验证目标、提交元数据,再移除旧来源。如果迁移失败,旧副本会保留,等待后续重试。

实现入口 ​

以下路径相对于仓库根目录:

路径职责
packages/platformVfsVolume 与平台文件系统契约
apps/web/src/libs/domain/file-storage.ts面向应用的存储契约
apps/web/src/libs/infrastructure/vfs/file-storage.ts提供方、挂载点、目录与文件生命周期
apps/web/src/libs/infrastructure/vfs/chunk-cache.ts已提交分块、恢复与内容校验
apps/web/src/libs/application/file-library-service.ts文件库引用与内容可用性

接下来想了解什么? ​

以 MIT 许可证开源 · 为设备之间的连接而构建