java实现文件分块上传与断点续传的核心是:将大文件切分为多个小块(chunk)按序上传,服务端记录已上传块状态;客户端上传前查询已存在块并跳过,从而支持断点续传。

Java 中实现文件分块上传与断点续传,核心在于将大文件切分为多个小块(chunk),按序上传,并在服务端记录已上传块的状态;客户端上传前先查询服务端已存在哪些块,跳过重复上传,从而支持断点续传。
一、前端分块与上传控制(以 JavaScript 为例,后端用 Java 接收)
前端负责切片、计算唯一标识、并发控制和状态校验:
- 使用
File.slice()或Blob.slice()按固定大小(如 2MB)切分文件 - 为每个块生成唯一标识:常用
file.name + file.size + chunkIndex或结合 MD5(对整个文件预计算一次,再传给后端用于校验完整性) - 上传时携带参数:
fileName、fileId(全局唯一 ID,如 UUID)、chunkIndex、totalChunks、chunkSize - 上传前发起
GET /api/upload/check?fileId=xxx&chunkIndex=5查询该块是否已存在,若返回200则跳过,否则 POST 上传
二、Java 后端接收与存储分块文件
使用 Spring Boot + MultipartFile 实现,关键点是避免内存溢出、保证线程安全、支持快速查重:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 配置
spring.servlet.multipart.max-file-size=500MB和max-request-size,但实际单次只收一个 chunk(几 MB),所以无需调得过大 - 定义上传接口,接收
@RequestParam MultipartFile file及其他元数据 - 将每个 chunk 存为独立文件,路径建议格式:
/upload/chunks/{fileId}/{chunkIndex},或统一存到对象存储(如 MinIO、OSS),用fileId_chunkIndex作 key - 用 Redis 缓存已上传块信息,例如:
SETEX upload:status:{fileId} 3600 "{\"uploadedChunks\":[0,1,3],\"total\":10}",便于快速响应校验请求
三、合并分块与完整性校验
当所有块上传完成(前端检测 uploadedChunks.length === totalChunks),触发合并逻辑:
- 前端调用
POST /api/upload/merge?fileId=xxx&fileName=xxx - 后端从 Redis 或数据库读取已上传块列表,按序读取所有 chunk 文件,用
Files.write(..., StandardOpenOption.APPEND)或FileChannel.transferFrom()高效合并 - 合并后计算最终文件的 MD5(或 SHA-256),与前端预传的文件总 MD5 对比,一致则确认上传成功,否则返回错误并清理临时块
- 合并成功后删除 Redis 中的上传状态和所有 chunk 文件(或设置 TTL 延迟清理)
四、断点续传的关键保障措施
真正让“断点续传”可靠,不只是跳过已传块,还要处理异常场景:
-
上传中失败重试:前端对单个 chunk 设置超时和重试次数(如 3 次),后端幂等处理——相同
fileId+chunkIndex的多次上传只保留一份 -
服务重启恢复:上传状态不能只存在内存,必须落库(MySQL 记录
file_id, chunk_index, status, create_time)或持久化 Redis -
过期清理:为每个
fileId设置上传有效期(如 24 小时),超时未合并则自动清理所有相关 chunk - 并发安全:多个 chunk 并发上传时,避免合并时文件被写入冲突,可用分布式锁(Redis Lock)或数据库乐观锁控制 merge 操作
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










