news 2026/4/18 0:00:32

国密加密在大文件上传插件中的实现与优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
国密加密在大文件上传插件中的实现与优化

大文件传输方案设计与实现方案

作为湖南XX软件公司的前端工程师,面对20G大文件传输的需求,我经过深入调研和分析后提出以下解决方案。

一、技术挑战分析

  1. 大文件传输

    • 20G文件直接上传会导致内存溢出
    • 网络中断后需要支持断点续传
    • 传输进度监控和速度控制
  2. 浏览器兼容性

    • IE8不支持现代文件API(File API)
    • 老浏览器不支持WebSocket和Fetch API
    • 跨浏览器行为不一致问题
  3. 加密要求

    • 前端实现SM4和AES加密
    • 密钥安全管理和传输
  4. 文件夹结构保持

    • 需要设计合理的数据结构表示层级
    • 后端需要支持多级目录存储

二、整体架构设计

前端方案

用户界面

文件分片

加密模块

上传队列

断点续传控制

进度监控

文件夹解析

后端方案

接收分片

分片校验

合并文件

存储加密

数据库记录

文件元数据

三、前端核心实现

1. 文件分片上传基础代码

// file-uploader.jsclassFileUploader{constructor(options){this.chunkSize=options.chunkSize||5*1024*1024;// 默认5MBthis.maxRetry=options.maxRetry||3;this.concurrent=options.concurrent||3;this.encryptAlgorithm=options.encryptAlgorithm||'AES';}asyncupload(file){consttotalChunks=Math.ceil(file.size/this.chunkSize);constfileHash=awaitthis.calculateFileHash(file);// 检查服务端已上传分片const{uploadedChunks}=awaitthis.checkServerStatus(file.name,fileHash);constuploadQueue=[];for(leti=0;i<totalChunks;i++){if(!uploadedChunks.includes(i)){uploadQueue.push(this.uploadChunk(file,i,fileHash));}}awaitPromise.all(uploadQueue.slice(0,this.concurrent));awaitthis.mergeChunks(file.name,fileHash,totalChunks);}asyncuploadChunk(file,chunkIndex,fileHash){conststart=chunkIndex*this.chunkSize;constend=Math.min(file.size,start+this.chunkSize);constchunk=file.slice(start,end);// 加密处理constencryptedChunk=awaitthis.encrypt(chunk);constformData=newFormData();formData.append('file',encryptedChunk);formData.append('chunkIndex',chunkIndex);formData.append('totalChunks',Math.ceil(file.size/this.chunkSize));formData.append('fileHash',fileHash);for(letattempt=0;attempt<this.maxRetry;attempt++){try{awaitaxios.post('/api/upload',formData,{onUploadProgress:(progressEvent)=>{this.updateProgress(chunkIndex,progressEvent.loaded/progressEvent.total);}});return;}catch(error){if(attempt===this.maxRetry-1)throwerror;}}}asyncencrypt(data){if(this.encryptAlgorithm==='SM4'){returnsm4Encrypt(data,this.encryptionKey);}else{returnaesEncrypt(data,this.encryptionKey);}}}

2. IE8兼容方案

// ie8-compat.jsfunctionsetupIEFallback(){if(!window.File||!window.FileReader||!window.FileList||!window.Blob){// 使用Flash或ActiveX后备方案document.getElementById('file-input').outerHTML=`您的浏览器不支持文件上传功能`;}}

3. 文件夹上传实现

// folder-uploader.jsasyncfunctionuploadFolder(folderInput){constentries=awaitgetFolderEntries(folderInput);conststructure={};for(constentryofentries){constrelativePath=entry.webkitRelativePath;constpathParts=relativePath.split('/');letcurrentLevel=structure;for(leti=0;i<pathParts.length-1;i++){constpart=pathParts[i];if(!currentLevel[part]){currentLevel[part]={};}currentLevel=currentLevel[part];}if(entry.isFile){constfile=awaitgetFileFromEntry(entry);currentLevel[pathParts[pathParts.length-1]]=file;}}awaituploadFolderStructure(structure);}asyncfunctionuploadFolderStructure(structure,basePath=''){for(const[name,content]ofObject.entries(structure)){constcurrentPath=basePath?`${basePath}/${name}`:name;if(contentinstanceofFile){// 上传文件constuploader=newFileUploader();awaituploader.upload(content,currentPath);}else{// 创建目录并递归上传内容awaitaxios.post('/api/createFolder',{path:currentPath});awaituploadFolderStructure(content,currentPath);}}}

四、后端核心实现

1. 分片接收接口

// UploadController.java@RestController@RequestMapping("/api")publicclassUploadController{@PostMapping("/upload")publicResponseEntityuploadChunk(@RequestParam("file")MultipartFilefile,@RequestParam("chunkIndex")intchunkIndex,@RequestParam("totalChunks")inttotalChunks,@RequestParam("fileHash")StringfileHash){try{// 解密处理byte[]decryptedData=decrypt(file.getBytes(),getEncryptionKey());// 存储分片StringtempDir=getTempDir(fileHash);Files.createDirectories(Paths.get(tempDir));PathchunkPath=Paths.get(tempDir,String.valueOf(chunkIndex));Files.write(chunkPath,decryptedData);returnResponseEntity.ok().build();}catch(Exceptione){returnResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}}@PostMapping("/merge")publicResponseEntitymergeChunks(@RequestParam("fileName")StringfileName,@RequestParam("fileHash")StringfileHash,@RequestParam("totalChunks")inttotalChunks){try{StringtempDir=getTempDir(fileHash);PathoutputPath=Paths.get(getStorageDir(),fileName);try(OutputStreamos=newFileOutputStream(outputPath.toFile())){for(inti=0;i<totalChunks;i++){PathchunkPath=Paths.get(tempDir,String.valueOf(i));byte[]chunkData=Files.readAllBytes(chunkPath);os.write(chunkData);}}// 存储加密encryptAndStore(outputPath,getStorageKey());// 清理临时分片FileUtils.deleteDirectory(newFile(tempDir));returnResponseEntity.ok().build();}catch(Exceptione){returnResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}}}

2. 文件夹结构存储设计

// FileEntity.java@Entity@Table(name="file_storage")publicclassFileEntity{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringname;privateStringpath;// 完整路径如 /folder/subfolder/file.txtprivatebooleanisDirectory;privateLongparentId;// 父目录IDprivateStringstorageKey;// 物理存储键privateStringencryptionAlgorithm;// SM4/AESprivateStringchecksum;privatelongsize;// 关系映射@OneToMany@JoinColumn(name="parentId")privateListchildren;// Getters and setters...}

3. 加密服务实现

// EncryptionService.java@ServicepublicclassEncryptionService{publicbyte[]encrypt(byte[]data,Stringalgorithm,Stringkey){if("SM4".equalsIgnoreCase(algorithm)){returnSM4Util.encrypt(data,key);}else{returnAESUtil.encrypt(data,key);}}publicbyte[]decrypt(byte[]data,Stringalgorithm,Stringkey){if("SM4".equalsIgnoreCase(algorithm)){returnSM4Util.decrypt(data,key);}else{returnAESUtil.decrypt(data,key);}}}

五、数据库设计

CREATETABLEfile_storage(idBIGINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(255)NOTNULL,pathVARCHAR(1024)NOTNULL,is_directoryBOOLEANNOTNULL,parent_idBIGINT,storage_keyVARCHAR(255),encryption_algorithmVARCHAR(10),checksumVARCHAR(64),sizeBIGINT,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,FOREIGNKEY(parent_id)REFERENCESfile_storage(id));CREATEINDEXidx_file_pathONfile_storage(path);CREATEINDEXidx_file_parentONfile_storage(parent_id);

六、部署与优化建议

  1. 前端优化

    • 使用Web Worker处理加密计算,避免UI阻塞
    • 实现自适应分片大小,根据网络质量动态调整
    • 添加本地存储记录,支持页面刷新后恢复上传
  2. 后端优化

    • 使用Nginx进行负载均衡和文件上传代理
    • 实现分布式文件存储,支持水平扩展
    • 添加Redis缓存已上传分片信息
  3. 安全建议

    • 实现密钥轮换机制
    • 添加文件完整性校验
    • 限制单个IP的上传速度和并发数

七、测试方案

  1. 单元测试

    • 分片功能测试
    • 加密/解密测试
    • 文件夹结构解析测试
  2. 集成测试

    • 跨浏览器测试
    • 大文件(20G+)传输测试
    • 断网恢复测试
  3. 性能测试

    • 并发上传测试
    • 网络限速环境测试
    • 服务器资源占用监控

此方案综合了现代Web技术和传统浏览器兼容性需求,采用分片上传、断点续传和加密传输等核心技术,能够满足20G大文件传输的需求,同时保持文件夹结构和跨平台兼容性。

设置框架

安装.NET Framework 4.7.2
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472
框架选择4.7.2

添加3rd引用

编译项目

NOSQL

NOSQL无需任何配置可直接访问页面进行测试

SQL

使用IIS
大文件上传测试推荐使用IIS以获取更高性能。

使用IIS Express

小文件上传测试可以使用IIS Express

创建数据库

配置数据库连接信息

检查数据库配置

访问页面进行测试


相关参考:
文件保存位置,

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

下载完整示例

下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 14:06:58

PID神经元网络遇上粒子群:给多变量系统做个解耦按摩

03-PID神经元网络解耦控制算法_多变量系统控制 本代码研究了基于PID神经元的多变量耦合系统控制&#xff0c;并用PSO算法来优化控制器以取得更好的控制效果。 网络结构&#xff1a;PID神经元网络可分为用于单变量系统控制的SPIDNN单输出神经元网络和多变量系统控制的MPIDNN神经…

作者头像 李华
网站建设 2026/4/18 7:38:28

Jupyter Notebook内核崩溃恢复PyTorch变量

Jupyter Notebook内核崩溃恢复PyTorch变量 在深度学习实验中&#xff0c;你是否经历过这样的场景&#xff1a;花了几个小时训练模型、处理数据、调试代码&#xff0c;终于快要出结果时——Jupyter 内核突然崩溃&#xff0c;所有变量瞬间清空&#xff0c;一切归零&#xff1f;这…

作者头像 李华
网站建设 2026/4/17 11:54:45

Markdown添加脚注:补充PyTorch技术细节

PyTorch-CUDA 容器化开发环境技术解析 在深度学习项目中&#xff0c;最让人头疼的往往不是模型设计本身&#xff0c;而是环境配置——“在我机器上能跑”成了团队协作时的经典难题。PyTorch 版本、CUDA 驱动、cuDNN 加速库之间的版本兼容性问题&#xff0c;常常让开发者耗费数小…

作者头像 李华
网站建设 2026/4/18 7:29:24

进程的创建与终止

文章目录进程创建fork函数多次fork()带来的问题创建“进程链”创建多个子进程进程终止return语句_exit()进程创建 fork函数 #include <unistd.h> pid_t fork(void);功能&#xff1a;创建子进程返回值&#xff1a; 父进程&#xff1a;返回子进程的PID&#xff08;>0&…

作者头像 李华
网站建设 2026/4/18 7:39:16

PyTorch安装过程中断?断点续传解决方案

PyTorch安装过程中断&#xff1f;断点续传解决方案 在深度学习项目启动阶段&#xff0c;最令人沮丧的场景之一莫过于&#xff1a;你已经等待了近一个小时&#xff0c;pip install torch 却因为网络波动突然中断。重试后再次失败——更糟的是&#xff0c;它并不会从中断处继续&a…

作者头像 李华
网站建设 2026/4/18 8:09:50

GitHub Gist分享PyTorch代码片段

构建即用型深度学习环境&#xff1a;PyTorch-CUDA 镜像的工程实践 在深度学习项目中&#xff0c;最让人头疼的往往不是模型调参或数据清洗&#xff0c;而是——“为什么你的代码在我机器上跑不起来&#xff1f;” 这个问题几乎成了AI开发者的集体记忆。明明复现的是顶会论文的开…

作者头像 李华