1. 大文件分块上传与断点续传技术解析
在企业级文件传输系统中,大文件上传一直是技术难点。传统单次上传方式存在网络波动敏感、内存占用高、失败后需重传等问题。我们团队通过自研分块上传方案,实现了稳定可靠的TB级文件传输能力。
核心原理:将大文件切割为5MB大小的分片,每个分片独立上传并记录状态。即使中途断网,也能从最后一个成功分片继续上传,避免重复传输已完成部分。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计要点
2.1 整体架构分层
系统采用前后端分离设计,主要分为四个逻辑层:
- 前端展示层:Vue2/React实现用户界面,包含文件选择器、进度展示等组件
- 分片调度层:控制分片上传顺序、失败重试机制
- 传输引擎层:处理分片合并、断点续传逻辑
- 存储服务层:对接阿里云OSS或本地文件系统
2.2 关键技术选型考量
选择技术栈时我们重点考虑以下因素:
- 兼容性:需支持IE8等老旧浏览器(央企常见要求)
- 安全性:满足国密SM4加密标准
- 稳定性:分片上传失败后能自动恢复
- 性能:支持10万级并发分片传输
最终采用的方案组合:
- 前端:Resumable.js增强版(IE8兼容)
- 加密:BouncyCastle国密SM4实现
- 存储:MySQL记录分片元数据
3. 核心实现代码详解
3.1 后端分片接收接口
java复制@RestController
@RequestMapping("/api/file")
public class FileTransferController {
@PostMapping("/upload")
public ResponseEntity uploadChunk(
@RequestParam("file") MultipartFile file,
@RequestParam("chunkNumber") int chunkNumber,
@RequestParam("totalChunks") int totalChunks,
@RequestParam("identifier") String identifier) {
try {
// 创建分片存储目录
Path tempDir = Paths.get("/tmp/upload/" + identifier);
Files.createDirectories(tempDir);
// 存储分片到临时文件
Files.write(tempDir.resolve("chunk-" + chunkNumber),
file.getBytes(),
StandardOpenOption.CREATE);
// 更新数据库记录
chunkService.updateChunkStatus(identifier, chunkNumber);
return ResponseEntity.ok("Chunk uploaded");
} catch (Exception e) {
return ResponseEntity.status(500)
.body("Upload failed: " + e.getMessage());
}
}
}
关键点说明:
- 每个分片以独立文件形式存储
- 使用identifier作为文件唯一标识
- 数据库实时更新分片上传状态
3.2 分片合并逻辑
java复制public void mergeChunks(String identifier, String fileName) throws IOException {
// 获取所有分片文件
Path tempDir = Paths.get("/tmp/upload/" + identifier);
List<Path> chunks = Files.list(tempDir)
.sorted(Comparator.comparing(p -> {
String name = p.getFileName().toString();
return Integer.parseInt(name.split("-")[1]);
}))
.collect(Collectors.toList());
// 创建目标文件
Path output = Paths.get("/data/uploads/" + fileName);
try (OutputStream os = Files.newOutputStream(output,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND)) {
// 按顺序合并分片
for (Path chunk : chunks) {
Files.copy(chunk, os);
Files.delete(chunk); // 合并后删除分片
}
}
// 更新数据库状态
taskService.markTaskComplete(identifier);
}
4. 前端实现关键代码
4.1 分片上传逻辑
javascript复制// FileUploader.vue
methods: {
uploadChunk(file, chunkNumber) {
const start = chunkNumber * this.chunkSize;
const end = Math.min(file.size, start + this.chunkSize);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('file', chunk);
formData.append('chunkNumber', chu
