1. 跨平台Java大文件切片上传实战指南
作为一名在Java领域摸爬滚打15年的老开发,最近刚完成一个极具挑战性的文件上传系统。客户要求用IE9浏览器上传20GB的文件夹,还要保留完整的目录结构——这就像要求用自行车送外卖还得跑出120公里时速。经过两个月的实战,我总结出一套完整的解决方案,现在把核心技术和踩过的坑都分享给大家。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计思路
2.1 整体架构设计
大文件上传系统需要解决三个核心问题:稳定性、兼容性和性能。我的方案采用前后端分离架构:
- 前端:基于WebUploader封装的上传组件,支持IE9+和现代浏览器
- 后端:SpringBoot + 阿里云OSS直传
- 数据库:MySQL记录文件树结构
- 缓存:Redis存储上传进度
这种架构的优势在于:
- 前端分片减轻服务器压力
- OSS直传避免服务器带宽瓶颈
- 进度信息独立存储支持断点续传
2.2 核心流程设计
文件上传的完整流程分为六个阶段:
- 预处理阶段:计算文件MD5,检查秒传
- 分片阶段:按5MB大小切割文件
- 上传阶段:并发上传分片到OSS
- 验证阶段:检查分片完整性
- 合并阶段:服务端合并分片
- 后处理阶段:记录文件结构,清理临时文件
提示:分片大小需要权衡网络环境和内存消耗,5MB是经过测试的平衡点
3. 前端关键技术实现
3.1 跨浏览器文件选择
现代浏览器使用webkitRelativePath获取完整路径,IE9需要特殊处理:
javascript复制// 现代浏览器获取文件夹路径
function getFolderPath(file) {
return file.webkitRelativePath || file.name;
}
// IE9兼容方案
function getIEFolderPath(fileInput) {
const path = fileInput.value;
return path.substring(0, path.lastIndexOf("\\"));
}
3.2 分片上传实现
核心分片上传逻辑:
javascript复制class ChunkUploader {
async upload(file, onProgress) {
const chunkSize = 5 * 1024 * 1024; // 5MB
const chunks = Math.ceil(file.size / chunkSize);
const fileMd5 = await calculateMd5(file);
// 检查秒传
if(await checkFastUpload(fileMd5)) {
return { skipped: true };
}
// 上传分片
for(let i=0; i<chunks; i++) {
const chunk = file.slice(i*chunkSize, (i+1)*chunkSize);
await uploadChunk(fileMd5, chunk, i);
// 更新进度
onProgress((i+1)/chunks * 100);
}
// 通知合并
await mergeChunks(fileMd5, file.name);
}
}
3.3 断点续传实现
利用localStorage保存进度:
javascript复制class ResumeService {
constructor() {
this.storageKey = 'upload_progress';
}
saveProgress(fileMd5, progress) {
const data = JSON.parse(localStorage.getIt
