海诚网站建设,为什么很多公司没自己的网站,国泰君安建设工程官方网站,企业网站建设网站制作开发者日记#xff1a;2023年11月20日 周一 晴 项目名称#xff1a;跨平台大文件传输系统#xff08;WebUploaderVue3JSP腾讯云COS#xff09; 项目背景与核心挑战
近期承接了一个高难度外包项目#xff0c;客户要求实现20G级文件/文件夹上传下载#xff0c;需满足以下硬…开发者日记2023年11月20日 周一 晴项目名称跨平台大文件传输系统WebUploaderVue3JSP腾讯云COS项目背景与核心挑战近期承接了一个高难度外包项目客户要求实现20G级文件/文件夹上传下载需满足以下硬性条件断点续传即使重启电脑进度不能丢失需持久化存储文件夹层级保留上传后需100%还原原始目录结构全浏览器兼容从IE8到现代浏览器Edge/Chrome/Firefox/Safari/Opera技术栈Vue3前端 JSP后端 MySQL数据库 腾讯云COS存储现存问题网上开源方案仅支持单文件上传无完整文件夹上传实现IE8的Flash上传存在安全策略限制腾讯云COS的分片上传API与百度OBS有差异需重新适配20G文件传输需解决内存溢出和超时问题技术方案设计前端架构Vue3 WebUploadergraph TD A[用户选择文件/文件夹] -- B{浏览器类型} B --|Chrome/Firefox| C[使用webkitdirectory API] B --|IE8| D[调用ActiveX控件递归读取] C D -- E[生成文件树结构] E -- F[计算文件MD5spark-md5] F -- G[分片上传WebUploader] G -- H[本地存储进度localStorage]后端架构JSP Servlet是否是否接收分片是否首片创建数据库任务记录更新分片进度存储分片到临时目录是否全部分片完成合并文件并上传COS返回继续上传指令关键数据库设计CREATETABLEupload_tasks(task_idVARCHAR(36)PRIMARYKEY,-- UUIDfile_md5VARCHAR(64)NOTNULL,relative_pathVARCHAR(512),-- 保留文件夹层级如 /docs/2023/total_chunksINT,uploaded_chunksINT,statusENUM(pending,uploading,completed,failed),cos_keyVARCHAR(1024),-- COS存储路径create_timeDATETIMEDEFAULTNOW());核心代码实现前端文件夹上传与断点续传Vue3// src/components/FolderUploader.vueimport{ref,onMounted}fromvue;importWebUploaderfromwebuploader;importSparkMD5fromspark-md5;exportdefault{setup(){consttaskListref([]);constuploaderref(null);// 初始化上传器兼容IE8constinitUploader(){constisIE8!!window.ActiveXObject||ActiveXObjectinwindow;uploader.valueWebUploader.create({swf:/static/Uploader.swf,// IE8回退server:/api/upload-chunk,chunked:true,chunkSize:isIE8?4*1024*1024:10*1024*1024,threads:isIE8?1:3,// IE8限制并发formData:{taskId:localStorage.getItem(currentTaskId)||}});// 恢复未完成任务restoreTasks();};// 递归解析文件夹跨浏览器consthandleFolderSelect(e){constfilese.target.files;if(!files.length)return;constparseFolder(entries,parentPath){for(letentryofentries){if(entry.isFile){constrelativePathparentPath?${parentPath}/${entry.name}:entry.name;addUploadTask(entry,relativePath);}elseif(entry.isDirectory){constdirReaderentry.createReader();dirReader.readEntries((newEntries){parseFolder(newEntries,parentPath?${parentPath}/${entry.name}:entry.name);});}}};// Chrome/Firefox使用webkitGetAsEntryif(files[0].webkitGetAsEntry){constentryfiles[0].webkitGetAsEntry();if(entry.isDirectory){constdirReaderentry.createReader();dirReader.readEntries(parseFolder);}else{addUploadTask(files[0],files[0].name);}}// IE8使用ActiveX代码省略};// 添加上传任务constaddUploadTask(file,relativePath){consttask{file,relativePath,md5:,chunkCount:Math.ceil(file.size/uploader.value.options.chunkSize)};// 计算文件MD5用于断点校验calculateFileMD5(file,(md5){task.md5md5;taskList.value.push(task);saveTaskToLocal(task);});};onMounted((){initUploader();document.getElementById(folderInput).addEventListener(change,handleFolderSelect);});return{taskList,uploader};}};后端JSP分片处理与COS上传// /api/upload-chunk.jsp% pageimportcom.qcloud.cos.COSClient, com.qcloud.cos.model.*%% pageimportjava.util.UUID, java.io.*%%// 1. 获取参数StringtaskIdrequest.getParameter(taskId);intchunkIndexInteger.parseInt(request.getParameter(chunkIndex));inttotalChunksInteger.parseInt(request.getParameter(totalChunks));StringfileMd5request.getParameter(fileMd5);StringrelativePathrequest.getParameter(relativePath);// 2. 保存分片StringtempDirapplication.getRealPath(/)/temp/taskId;FiledirnewFile(tempDir);if(!dir.exists())dir.mkdirs();PartfilePartrequest.getPart(file);StringchunkPathtempDir/chunk_chunkIndex;filePart.write(chunkPath);// 3. 更新数据库try(ConnectionconnDriverManager.getConnection(jdbc:mysql://localhost:3306/file_transfer,user,pass);PreparedStatementstmtconn.prepareStatement(UPDATE upload_tasks SET uploaded_chunks? WHERE task_id?)){stmt.setInt(1,chunkIndex1);stmt.setString(2,taskId);stmt.executeUpdate();}// 4. 检查是否全部上传完成booleanisCompletefalse;try(ConnectionconnDriverManager.getConnection(jdbc:mysql://localhost:3306/file_transfer,user,pass);ResultSetrsconn.createStatement().executeQuery(SELECT uploaded_chunks, total_chunks FROM upload_tasks WHERE task_idtaskId)){if(rs.next()){isCompleters.getInt(uploaded_chunks)rs.getInt(total_chunks);}}// 5. 合并并上传COSif(isComplete){StringfinalPathtempDir/final_fileMd5;mergeChunks(tempDir,finalPath,totalChunks);// 合并逻辑省略// 腾讯云COS上传COSClientcosClientnewCOSClient(secretId,secretKey,region);StringcosKeyuploads/taskId/relativePath;cosClient.putObject(newPutObjectRequest(your-bucket,cosKey,newFile(finalPath)));// 清理临时文件deleteDirectory(newFile(tempDir));}out.print({\status\:\success\});%关键问题解决IE8文件夹上传使用配合ActiveX的FileSystemObject递归读取需用户手动设置IE安全级别为低客户要求已文档说明腾讯云COS分片校验上传前通过COSObject的doesObjectExist方法检查分片是否已存在20G文件内存优化采用流式处理避免一次性加载整个文件到内存JSP设置request.setAttribute(maxPostSize, 21474836480)20GB求助与社区支持目前IE8的ActiveX方案在Windows 10上存在权限问题已在QQ群374992201发布详细错误日志。完整代码已上传至Gitee待脱敏急需大神协助解决ActiveX控件在Win10的兼容性问题大文件合并时的内存溢出优化跨浏览器进度条同步显示明日计划编写自动重试机制和COS上传失败后的回滚逻辑确保20G文件传输的稳定性。日记结束附技术栈对比表模块原方案当前方案优化点前端框架jQueryVue3 Composition API响应式数据管理上传组件WebUploader基础版定制版支持文件夹断点递归解析文件夹结构后端语言PHPJSP利用Servlet处理大文件流对象存储百度OBS腾讯云COS适配不同的分片API规范如需完整项目或调试协助请联系QQ群或留言获取测试账号导入项目导入到Eclipse点南查看教程导入到IDEA点击查看教程springboot统一配置点击查看教程工程NOSQLNOSQL示例不需要任何配置可以直接访问测试创建数据表选择对应的数据表脚本这里以SQL为例修改数据库连接信息访问页面进行测试文件存储路径up6/upload/年/月/日/guid/filename效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。下载示例点击下载完整示例