分片上传的协调逻辑必须由后端主导,前端仅负责切片并携带序号和uploadId发起请求;Iris需通过原始body读取分片(非FormFile),合并时用io.Copy追加写入并校验顺序与完整性,Redis用于原子化状态管理。

分片上传的核心逻辑在前端还是后端?
分片上传的协调逻辑必须由后端主导,前端只负责按规则切片、携带分片序号和唯一标识(如 uploadId)发起请求。Iris 本身不内置分片管理,但能用标准 HTTP 处理 + 自定义状态存储完成整套流程。关键不是“Iris 怎么传”,而是“怎么用 Iris 接住每一片并组装”。
如何用 ctx.FormFile() 正确接收单个分片?
Iris 的 ctx.FormFile("file") 可以正常读取 multipart 表单中的文件字段,但要注意:分片上传通常用 application/octet-stream 或自定义 body(非 form-data),此时不能依赖 FormFile。更稳妥的做法是直接读取原始 body:
data, err := io.ReadAll(ctx.Request().Body)
if err != nil {
ctx.StatusCode(400)
ctx.WriteString("read body failed")
return
}
常见错误:前端用 fetch 发送 Blob 时未设 Content-Type: application/octet-stream,导致 Iris 解析失败;或后端误用 FormFile 试图从空表单里取文件。
- 若坚持用 form-data,确保前端每个分片都带
file字段和chunkIndex、totalChunks、uploadId等字段 - 若用 raw body,后端需统一约定分片命名规则(如
/{uploadId}/{chunkIndex}) - 务必校验
Content-Length是否与预期分片大小一致,防截断或伪造
分片合并时用 os.OpenFile 追加写入要注意什么?
合并不能简单把所有分片 os.ReadFile 后拼接,大文件会爆内存。正确方式是逐个打开分片文件,用 io.Copy 追加到目标文件:
f, _ := os.OpenFile(finalPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) defer f.Close() chunkFile, _ := os.Open(chunkPath) defer chunkFile.Close() io.Copy(f, chunkFile)
容易踩的坑:
- 没加
os.O_APPEND导致覆盖写入,最终文件只有最后一片内容 - 没按
chunkIndex顺序合并,文件结构错乱(尤其视频/图片会直接损坏) - 合并前未检查所有分片是否已上传完成(建议用 Redis 记录每个
uploadId的已收分片索引集合) - 合并后没删临时分片,磁盘悄悄被占满
怎么用 Redis 做分片状态协调?
单机部署可用 map + sync.RWMutex,但生产环境必须用 Redis。典型键设计:
-
upload:→ Set 类型,存已上传的uploadId:chunkschunkIndex(如 "0", "1", "2") -
upload:→ Hash,存uploadId:metafileName、totalChunks、size等元信息
每次收到分片,先 SADD 到 chunks 集合,再 SCARD 检查是否收齐。收齐后触发合并,并用 DEL 清理两个 key。注意:Redis 操作必须原子化,避免并发上传同一 uploadId 时状态错乱。
真正麻烦的不是代码,是分片重传、网络中断、客户端崩溃后的状态恢复——这些得靠 uploadId 的幂等性 + 客户端轮询服务端已收分片列表来兜底。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











