大文件上传
- 文件分片
- 基于文件内容的分片命名,如 hash, 用 sparkMd5 来计算出文件内容的 hash 名。根据 hash 查看后端是否有这个文件来决定是否要上传。
- 计算整个文件的 hash ,然后查看后端是否已经存储,如果已经存储就不需要上传了。
- 计算 hash 是个 cpu 密集型操作,是在主线程完成的,会导致页面渲染阻塞。
- 通过多线程 + 异步的方式(webwork)去完成计算 hash。或者采用 react 的时间分片的模式(requestIdleCallback)
流程
- 先上传文件的基本信息如 name、size、分片数量等等 。后端返回一个唯一标识来标识这个文件上传的请求。
- 发送 hash,进行 hash 校验。进行单个 hash 和整个文件的 hash 的校验,返回是否需要继续上传。
- 分片上传。传入 hash、index(这次文件上传的编号)、文件内容
- 文件合并请求。后端合并所有分片,返回文件的存储地址。合并并不是真的合并,只是校验分片的大小、数量等等。
设计
- 发布订阅模式
- 多任务并发类,完成计算 hash 和文件上传的控制。
- 分片函数
- 后端服务器只保存分片,通过指针(某个属性如Nexthash,指向下一个分片的索引)查找下一个分片。
- 生产文件访问地址
- 获取文件时,获取文件的分片信息,通过文件流的方式逐步读取分片内容然后输出到网络流。