IndexedDB可通过手动分片实现大文件可靠存取:将文件切为1–5MB的Blob片段,用files和chunks两个objectStore分别存储元数据与二进制数据,逐片事务写入并支持错误回滚,按序读取合并;关键在于校验、进度持久化与残留清理。

IndexedDB 本身不直接支持“分片上传”或“断点续传”这类网络语义,但可以通过手动将大文件切分为多个 Blob 或 ArrayBuffer 片段,分别存入数据库,并记录元信息(如文件名、总片数、当前索引、是否完成等),从而实现大文件的可靠分片存取。
分片前的准备:获取文件并确定分片大小
用户选择文件后,用 File 对象(继承自 Blob)调用 slice() 方法切分。推荐单片大小在 1–5 MB 之间——太小会增加事务开销和索引压力;太大可能触发内存警告或阻塞主线程。
- 用
file.size计算总片数:Math.ceil(file.size / chunkSize) - 每片用
file.slice(start, end)提取,返回新Blob - 建议在
Worker中做切片和读取,避免阻塞 UI
设计合理的对象存储结构
不要把所有文件碎片塞进一个 objectStore。推荐两个 objectStore 协同管理:
-
files:存文件元数据,主键为自定义 ID(如
uuid或file.name + timestamp),含name、size、totalChunks、uploadedChunks、status("uploading"/"done"/"error")等字段 -
chunks:存二进制片段,主键可设为复合键
[fileId, index](需用keyPath: ['fileId', 'index']或用indexedDB.openKeyCursor配合index查询);值为{ fileId, index, data: ArrayBuffer }
分片写入:逐片事务 + 错误回滚
每次只写一片,用单个事务包裹该片写入 + 元数据更新。失败时可重试,或标记该片失败后跳过(后续靠校验恢复)。
立即学习“Java免费学习笔记(深入)”;
- 打开事务,同时访问
files和chunksstore - 先读取
files中对应记录,更新uploadedChunks++ - 再写入
chunks:使用put({ fileId, index, data }) - 事务成功后继续下一片;失败则捕获
transaction.onabort或request.onerror,记录错误并暂停
合并读取:按序加载片段并组装 Blob
读取时先查 files 获取总片数和 ID,再用游标或多次 get 按 index 从小到大拉取所有 chunks,最后用 new Blob(chunksArray, {type: ...}) 合并。
- 可用
IDBIndex在chunks上按fileId建索引,再用openCursor(IDBKeyRange.only(fileId))遍历 - 注意顺序:
index字段必须是数字,且查询时确保升序遍历(默认就是) - 大文件合并建议用
ReadableStream或分批postMessage到 Worker,避免内存峰值
不复杂但容易忽略的是:分片不是目的,可靠性和可恢复性才是关键。加上校验(如每片 SHA-256)、进度持久化、以及清理机制(失败后自动删残留碎片),才能真正落地。


















