文件断点续传完整方案

文件断点续传(断点上传)完整实现方案(后端视角)

适用场景:大文件上传、弱网环境、移动端上传、失败可恢复、避免重复上传

技术栈示例:HTTP + Java + Redis + MySQL + 对象存储(OSS / COS / S3)


一、什么是文件断点续传

断点续传 = 文件分片上传 + 状态记录 + 可恢复上传

核心思想:

  • 把一个大文件切成多个 Chunk(分片)
  • 每个分片单独上传
  • 服务端记录已上传分片
  • 中断后只补传缺失分片

一句话:上传失败 ≠ 重来,而是从"断点"继续


二、为什么一定要用断点上传

1️⃣ 解决的问题

问题 普通上传 断点上传
大文件 ❌ 容易失败 ✅ 稳定
网络抖动 ❌ 重来 ✅ 续传
用户体验 ❌ 崩溃 ✅ 友好
带宽浪费 ❌ 严重 ✅ 可控

2️⃣ 典型场景

  • 视频 / 音频 / 安装包
  • 企业网盘
  • IM 文件发送
  • 后台管理系统上传 Excel / 压缩包

三、整体架构设计(后端视角)

复制代码
Client
  ↓(分片)
Upload API
  ↓
Redis(上传状态)
  ↓
临时分片存储(磁盘 / OSS)
  ↓
合并服务
  ↓
最终文件存储(OSS / 本地)

关键点:

  • Redis:记录分片上传进度
  • OSS:避免服务端磁盘爆炸
  • 合并操作:必须保证原子性

四、核心概念定义

1️⃣ 文件唯一标识(fileId)

通常使用:

复制代码
fileId = MD5(文件内容)

作用:

  • 秒传(已存在直接返回)
  • 断点识别
  • 去重

2️⃣ 分片参数

参数 含义
chunkIndex 当前分片索引(从 0 开始)
chunkSize 分片大小(如 5MB)
totalChunks 总分片数
fileId 文件唯一标识

五、接口设计(非常关键)

1️⃣ 初始化上传

接口

复制代码
POST /upload/init

请求

json 复制代码
{
  "fileId": "md5值",
  "fileName": "test.zip",
  "fileSize": 10240000,
  "chunkSize": 5242880
}

返回

json 复制代码
{
  "uploadedChunks": [0,2,3]
}

👉 客户端只上传缺失分片


2️⃣ 上传分片

复制代码
POST /upload/chunk

参数

  • fileId
  • chunkIndex
  • MultipartFile chunk

服务端逻辑

  1. 校验分片合法性
  2. 保存分片
  3. Redis 记录已上传 chunkIndex

3️⃣ 合并分片

复制代码
POST /upload/merge

流程

  1. 校验所有分片是否齐全
  2. 按顺序合并
  3. 生成最终文件
  4. 清理分片 & Redis

六、Redis 设计(重点)

1️⃣ Key 设计

复制代码
upload:{fileId}

2️⃣ Value 结构

text 复制代码
Set<Integer> uploadedChunks

或:

text 复制代码
Bitmap(更省内存)

3️⃣ 为什么用 Redis

  • 高并发
  • 原子操作
  • 进度查询快
  • 自动过期

七、Java 后端核心代码示例

1️⃣ 保存分片

java 复制代码
String key = "upload:" + fileId;
redisTemplate.opsForSet().add(key, chunkIndex);

2️⃣ 校验是否上传完成

java 复制代码
Long count = redisTemplate.opsForSet().size(key);
if (count == totalChunks) {
    // 允许合并
}

八、分片合并的坑(一定要看)

❌ 常见错误

  • 合并过程中进程挂了
  • 多个请求同时触发 merge
  • 合并顺序错乱

✅ 正确做法

  1. 分布式锁

    lock:merge:{fileId}

  2. 顺序合并

    chunk_0 → chunk_1 → chunk_2

  3. 临时文件 + rename

rename 在 Linux 下是原子操作


九、秒传是怎么实现的

流程:

  1. 客户端计算 MD5
  2. init 接口检查数据库
  3. 已存在 → 直接返回 URL
java 复制代码
if (fileExists(fileId)) {
    return "秒传成功";
}

本质:去重,不是快,是不传


十、断点上传 vs 对象存储直传

方案 特点
后端中转 控制力强
OSS 分片上传 性能最好
OSS + 回调 企业级最优解

强烈建议:

大文件 = OSS 分片上传 + 后端校验


十一、生产级优化建议

  • 分片大小:5MB ~ 10MB
  • Redis Key 设置过期时间
  • 合并操作异步化
  • 上传限流(防止刷接口)
  • 上传鉴权(防止任意文件)

相关推荐
CodeToGym3 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel
凡人叶枫3 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
JMchen1233 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
阔皮大师4 小时前
INote轻量文本编辑器
java·javascript·python·c#
小法师爱分享4 小时前
StickyNotes,简单便签超实用
java·python
qq_297574674 小时前
Linux 服务器 Java 开发环境搭建保姆级教程
java·linux·服务器
金牌归来发现妻女流落街头4 小时前
【从SpringBoot到SpringCloud】
java·spring boot·spring cloud
毅炼4 小时前
Java 基础常见问题总结(4)
java·后端
GR2342344 小时前
2025年影视仓TV+手机官方版 内置地址源支持高清直播
java·智能手机·软件
程序员清风4 小时前
北京回长沙了,简单谈谈感受!
java·后端·面试