秒传判断必须基于文件内容SHA256哈希,不可依赖文件名或大小;需流式计算避免OOM,用io.Copy配合sha256.New(),哈希存BINARY(32)并加唯一索引,服务端校验须绑定HMAC token防篡改。

秒传判断逻辑必须基于文件内容哈希,不能依赖文件名或大小
仅靠 os.Stat 获取的文件大小或名称做秒传判断,必然失效——同名不同内容、同大小不同数据的情况太常见。真正可靠的依据是文件内容的确定性哈希,推荐用 sha256(兼顾安全性和性能),而非 md5(碰撞风险高,云厂商如阿里云 OSS、腾讯云 COS 的秒传接口也明确要求 SHA256)。注意:哈希计算必须在上传前完成,且不能跳过大文件分块读取,否则内存溢出。
- 对超大文件(>1GB),务必用
io.Copy配合hash.Hash分块计算,避免ioutil.ReadFile一次性加载 - 哈希结果需转为十六进制字符串(
fmt.Sprintf("%x", hash.Sum(nil))),与云存储服务约定的哈希格式一致 - 某些 SDK(如 AWS S3)不原生支持秒传校验,需自行调用
HeadObject+ 对比 ETag(但 ETag 不一定是 SHA256,慎用)
各云厂商 SDK 对秒传的支持方式差异明显
阿里云 OSS 的 PutObject 接口支持 X-Oss-Content-Sha256 header 直接透传哈希值,服务端自动比对;腾讯云 COS 要先调用 HeadObject 查询对象是否存在,再手动比对 Content-MD5 或自定义元数据里的 x-cos-meta-sha256;而 AWS S3 完全不提供服务端哈希校验,只能自己实现「先查后传」逻辑。
- 阿里云 OSS:设置
PutObjectOptions中的ContentSha256字段,SDK 会自动添加 header - 腾讯云 COS:需在上传前用
client.Object.Get请求,检查响应头中x-cos-hash-sha256是否匹配 - AWS S3:无服务端哈希校验,只能用
HeadObject查是否存在,再结合自建元数据表或 Redis 缓存哈希映射
并发上传时哈希缓存和状态同步容易引发重复计算
多个 goroutine 同时处理同一文件路径,若各自独立计算 SHA256,会造成 CPU 和 I/O 浪费。更糟的是,若秒传判断和实际上传之间存在窗口期(比如 A 判断不存在、开始上传,B 同时也判断不存在、也上传),导致同一文件被写入两次。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 用
sync.Map缓存已计算的filepath → sha256映射,key 用绝对路径 + 文件 size + modtime 组合防误击 - 秒传判定阶段加分布式锁(如 Redis SETNX)或本地文件锁(
flock),确保「查—判—传」原子性 - 上传成功后,立即将哈希写入持久化缓存(如 Redis),避免重启后重复计算
断点续传与秒传逻辑必须解耦,否则上传中断后无法恢复
秒传本质是「跳过上传」,而断点续传是「接着传」。如果把两者混在同一函数里(比如上传前先查哈希,查不到就走分片上传),一旦分片上传中途失败,下次再进函数会重新查哈希——此时文件可能已被部分上传,但服务端尚未完成合并,查不到完整对象,导致重复分片上传。
立即学习“go语言免费学习笔记(深入)”;
- 秒传只作用于「完整对象已存在」场景,逻辑入口应独立于上传主流程
- 断点续传需维护分片 ID 和已上传 offset,保存到本地临时文件或数据库,与哈希无关
- 建议将秒传作为上传前的快速过滤层:若命中,直接返回 success;未命中,才进入带状态恢复的分片上传流程

















