IndexedDB本身不直接支持分片存储,但可通过手动切分大文件为Blob或ArrayBuffer片段并分别存入数据库,配合元信息记录实现逻辑分片与恢复;关键在于合理设计schema、控制事务边界、逐片读取避免内存溢出,并按复合键有序存取以确保拼接正确。

IndexedDB 本身不直接支持“分片存储”,但可以通过手动将大文件切分成多个 Blob 或 ArrayBuffer 片段,分别存入数据库,并记录元信息(如文件名、总大小、分片序号、总片数等),实现逻辑上的分片存储与恢复。关键在于合理设计 schema、控制事务边界、避免内存溢出,并确保恢复时能按序拼接。
分片上传:把大文件切成块再存
浏览器中读取大文件通常用 File.slice() 或 Blob.slice() 按固定大小(如 1MB)切片,每片单独写入 IndexedDB。注意不要一次性读取整个文件到内存(比如不用 FileReader.readAsArrayBuffer 全量读),而应逐片读取 + 存储。
- 定义分片大小(例如
CHUNK_SIZE = 1024 * 1024),计算总片数:Math.ceil(file.size / CHUNK_SIZE) - 用
for循环或递归方式,每次调用file.slice(start, end)获取当前分片 - 每个分片存为一条记录,keyPath 可设为
[fileName, chunkIndex]复合键,便于后续查询和排序 - 额外存一条元数据记录(如
fileMetastore),包含fileName、totalSize、chunkCount、uploadTime等
事务控制与错误处理
单个事务不宜写入过多分片(如超过 50 片可能触发 QuotaExceededError 或阻塞 UI),建议每 10–20 片一个事务,并捕获 abort 和 error 事件。失败时需清理已存片段,或标记断点以便续传。
- 使用
db.transaction(['chunks'], 'readwrite')显式指定 store,避免隐式事务冲突 - 对每个分片调用
objectStore.add(chunkBlob, [fileName, index]),key 使用数组保证有序 - 监听事务
oncomplete后再发起下一批;onerror中调用transaction.abort()并记录失败位置 - 可选:在元数据中保存
lastSuccessIndex,支持断点续传
分片恢复:按序读取并合并成完整文件
恢复时先查元数据获取总片数和文件名,再用 IDBKeyRange 查询所有该文件的分片(按 [fileName, chunkIndex] 升序),最后用 Blob([blob1, blob2, ...]) 或 Uint8Array 合并。
立即学习“Java免费学习笔记(深入)”;
- 打开只读事务,从
fileMetastore 读取元信息 - 用
IDBKeyRange.bound([fileName, 0], [fileName, Infinity])查询chunksstore,确保按chunkIndex自然排序 - 用
cursor.continue()遍历结果,收集所有 Blob;顺序由 key 决定,无需额外排序 - 合并时推荐
new Blob(blobArray, {type: originalType}),比手动拼接 ArrayBuffer 更安全高效
优化与注意事项
实际应用中还需考虑磁盘配额、并发读写、跨会话一致性等问题。IndexedDB 的存储上限因浏览器而异(通常为硬盘空闲空间的 50%~80%,但有硬限制如 Chrome 单 origin 约 60%),大文件长期存储建议配合定期清理策略。
- 避免在主线程长时间处理大 Blob —— 可将读取/合并逻辑移到 Web Worker
- 恢复前检查各分片是否存在且完整(可存 MD5 或 size 校验字段)
- 删除文件时,先删元数据,再批量删对应所有分片(同样用复合 key 范围删除)
- IndexedDB v3+ 支持
getAll(),但大数据量仍建议用游标流式读取,防止内存暴涨


















