vue java实现分片上传
分片上传的实现原理
分片上传是将大文件分割成多个小块分别上传,最后在服务器合并的技术。这种方式能解决大文件上传超时、网络不稳定等问题,同时支持断点续传。
前端Vue实现
前端需要使用File API将文件切片,并通过axios发送分片请求。核心代码示例:
// 文件切片
function createFileChunks(file, chunkSize = 5 * 1024 * 1024) {
const chunks = []
let cur = 0
while (cur < file.size) {
chunks.push(file.slice(cur, cur + chunkSize))
cur += chunkSize
}
return chunks
}
// 上传分片
async function uploadChunks(chunks, fileMd5) {
const requests = chunks.map((chunk, index) => {
const formData = new FormData()
formData.append('file', chunk)
formData.append('chunkIndex', index)
formData.append('fileMd5', fileMd5)
return axios.post('/api/upload/chunk', formData)
})
await Promise.all(requests)
}
后端Java实现
Spring Boot后端需要处理分片上传和合并逻辑。关键代码示例:
@PostMapping("/upload/chunk")
public ResponseEntity<?> uploadChunk(
@RequestParam("file") MultipartFile file,
@RequestParam("chunkIndex") int chunkIndex,
@RequestParam("fileMd5") String fileMd5) {
String chunkDir = "uploads/chunks/" + fileMd5 + "/";
new File(chunkDir).mkdirs();
String chunkPath = chunkDir + chunkIndex;
file.transferTo(new File(chunkPath));
return ResponseEntity.ok().build();
}
@PostMapping("/merge")
public ResponseEntity<?> mergeChunks(
@RequestParam("fileName") String fileName,
@RequestParam("fileMd5") String fileMd5,
@RequestParam("totalChunks") int totalChunks) {
String chunkDir = "uploads/chunks/" + fileMd5 + "/";
String outputPath = "uploads/" + fileName;
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
for (int i = 0; i < totalChunks; i++) {
File chunkFile = new File(chunkDir + i);
Files.copy(chunkFile.toPath(), fos);
chunkFile.delete();
}
new File(chunkDir).delete();
}
return ResponseEntity.ok().build();
}
进度监控实现
前端可以通过axios的onUploadProgress回调实现进度显示:
const config = {
onUploadProgress: progressEvent => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
console.log(`上传进度: ${percent}%`)
}
}
axios.post('/api/upload/chunk', formData, config)
断点续传实现
后端需要记录已上传的分片信息:
@GetMapping("/upload/progress")
public ResponseEntity<?> getUploadProgress(
@RequestParam("fileMd5") String fileMd5) {
String chunkDir = "uploads/chunks/" + fileMd5 + "/";
File dir = new File(chunkDir);
if (!dir.exists()) {
return ResponseEntity.ok(Collections.emptyList());
}
return ResponseEntity.ok(Arrays.stream(dir.listFiles())
.map(f -> Integer.parseInt(f.getName()))
.collect(Collectors.toList()));
}
注意事项
文件MD5计算应在前端完成,作为文件唯一标识。分片大小建议设置为1-5MB。后端需要做好并发控制和错误处理,确保分片上传的原子性。






