Java文件分块断点续传需客户端分片标记序号并计算MD5,服务端持久化状态、校验MD5后合并,上传前查询已传块实现续传,关键在可识别、可跳过、可合并。

Java 中实现文件分块断点续传,核心在于「客户端分片上传 + 服务端记录进度 + 上传前校验已传片段」。关键不是单纯切文件,而是让每次上传可识别、可跳过、可合并。
一、客户端:按固定大小切片并标记序号
用 RandomAccessFile 或 Files.readAllBytes() 读取文件,按预设块大小(如 5MB)切分,每块生成唯一标识(如 fileId + chunkIndex),同时计算该块的 MD5(用于去重和完整性校验)。
- 避免内存溢出:用
FileInputStream+BufferedInputStream流式读取,边读边写入临时块文件或直接上传 - 块序号从 0 开始连续编号,总块数提前通过
file.length() / chunkSize + 1算出 - 上传请求中携带:文件 ID、块索引、总块数、块 MD5、是否为最后一块
二、服务端:持久化上传状态并支持秒传与续传
服务端收到上传请求后,先查数据库或 Redis 中该文件 ID + 块索引是否存在。若已存在且 MD5 匹配,直接返回“已存在”,跳过存储;否则保存块数据(建议存入本地磁盘或对象存储,并记录元数据)。
- 推荐用轻量级表:
upload_chunk(file_id, chunk_index, md5, status, create_time),status 可为 uploading / success / failed - 上传完成时,触发合并逻辑:按 chunk_index 升序读取所有成功块,用
FileOutputStream追加写入目标文件 - 合并前校验总块数和每块 MD5,任一不匹配则拒绝合并,防止损坏
三、断点续传的关键逻辑:上传前主动探测
客户端发起上传前,先向服务端发起一个「查询已传块」请求(如 GET /api/upload/status?fileId=xxx),服务端返回已成功上传的 chunkIndex 列表。客户端据此跳过这些块,只上传剩余部分。
立即学习“Java免费学习笔记(深入)”;
- 网络中断后重启,客户端重新拉取状态,从第一个缺失的块继续
- 建议增加「心跳保活」或「超时清理」机制:对 24 小时未更新的 uploading 状态块设为 failed,避免脏数据堆积
- 前端可配合显示「已传 12/38 块」,提升用户体验
四、进阶优化建议
生产环境可叠加以下能力提升健壮性:
- 使用
CompletableFuture并行上传非相邻块(注意服务器并发限制) - 块上传加签名(如 HMAC-SHA256),防篡改和未授权上传
- 大文件场景下,服务端用零拷贝(
FileChannel.transferTo)加速合并 - 接入 MinIO 或阿里 OSS 时,利用其
Multipart Upload原生接口,比自研更稳定
不复杂但容易忽略:MD5 校验必须在服务端重算一次,不能只信客户端传来的值;合并操作要加分布式锁(如 RedisLock),避免多终端同时触发导致文件错乱。


















