indexeddb 可高效存储大文件,推荐用 arraybuffer(而非 base64 字符串);超大文件需分块存储并记录元数据;读取后通过 blob 和 url.createobjecturl 实现预览或下载,注意及时释放内存。

JavaScript 中使用 IndexedDB 存储大文件或二进制数据是可行的,关键在于正确处理 Blob、ArrayBuffer 或 File 对象,并避免直接存字符串(比如 base64),否则会显著降低性能、增加内存开销甚至触发存储限制。
把文件转成 ArrayBuffer 再存入对象仓库
IndexedDB 原生支持 ArrayBuffer 和 Blob 类型,推荐优先使用 ArrayBuffer —— 它更轻量、可随机读写,也便于后续解析(如解码图片、解析音频元数据等)。
- 用
file.arrayBuffer()(File实例方法)直接获取 ArrayBuffer,无需 FileReader - 打开数据库后,在事务中调用
objectStore.put(arrayBuffer, key)即可保存 - 注意:key 可以是字符串、数字或 Date,但不能是 ArrayBuffer 本身(它不可作为 key)
分块存储超大文件(如 >100MB)以避免阻塞和内存溢出
单次写入几百 MB 的 ArrayBuffer 可能导致主线程卡顿、内存飙升,甚至被浏览器中断。对超大文件(如视频、备份包),建议手动分块:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用
file.slice(start, end)切出 Blob 片段,再转为 ArrayBuffer - 每块存为一条记录,key 设计为
`${fileId}_chunk_${index}` - 额外存一条元数据记录(如文件名、总大小、分块数、MIME 类型),方便还原
- 读取时按序拉取所有 chunk,用
new Blob(chunkArray, {type})合并回完整文件
读取后正确构造 Blob 或 URL 供下载/预览
从 IndexedDB 读出的 ArrayBuffer 需要转换为可用格式:
- 显示图片/播放音视频:用
URL.createObjectURL(new Blob([arrayBuffer], {type: 'image/png'}))得到 blob URL - 触发下载:创建 a 标签 +
download属性,点击后调用URL.revokeObjectURL()释放内存 - 避免长期持有 blob URL,尤其在大量文件场景下,否则内存不释放
注意兼容性与错误边界
虽然现代浏览器均支持 ArrayBuffer/Blob 存储,但仍需留意:
- 旧版 Safari(iOS onerror 和
onsuccess显式监听 - IndexedDB 有配额限制(通常为磁盘空闲空间的 ~50%),但首次写入大文件时可能触发用户授权弹窗(Chrome/Firefox 在非安全上下文或隐身模式下更敏感)
- 不要用
JSON.stringify()处理二进制数据;base64 编码后再存不仅体积增 33%,还会让索引失效、无法流式读取
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










