ICML 2026|武汉大学 悉尼大学: 多模态模型越练越会想?它可能只是越练越会“猜”
2026/5/16 21:05:44
《政府信创项目大文件传输攻坚实录:从开源困境到自研方案的破局之路》
——北京.NET程序员的国产化适配实战
作为某政府招投标项目的核心开发成员,我负责实现20GB级大文件传输系统,需满足以下严苛要求:
功能需求:
兼容性要求:
技术栈限制:
开源评估惨败:
结论:开源无解,必须自研。
// src/components/FolderUploader.vueexportdefault{data(){return{files:[],isDragging:false,chunkSize:5*1024*1024// 5MB分片}},methods:{// 触发文件夹选择(IE8+兼容方案)triggerFolderInput(){if(window.FileReader&&window.File&&window.FileList&&window.Blob){// 现代浏览器使用input[type=file] webkitdirectorythis.$refs.folderInput.setAttribute('webkitdirectory','')this.$refs.folderInput.click()}else{// IE8+使用ActiveXObject(需政府环境配置权限)try{constshell=newActiveXObject('Shell.Application')constfolder=shell.BrowseForFolder(0,'请选择文件夹',0)if(folder){this.scanFolderIE(folder)}}catch(e){this.$message.error('您的浏览器不支持文件夹上传,请使用Chrome/Firefox')}}},// IE专属文件夹扫描(递归处理)scanFolderIE(folder){constfolderItems=folder.Items()for(leti=0;i<folderItems.Count;i++){constitem=folderItems.Item(i)if(item.IsFolder){this.scanFolderIE(item.GetFolder)}elseif(item.Path){this.files.push({name:item.Name,path:item.Path,size:item.Size,lastModified:item.ModifyDate})}}},// 文件分片上传(通用方案)asyncuploadFile(file){constfileId=this.calculateFileId(file)// MD5生成唯一IDconstchunks=Math.ceil(file.size/this.chunkSize)for(leti=0;i<chunks;i++){conststart=i*this.chunkSizeconstend=Math.min(file.size,start+this.chunkSize)constchunk=file.slice(start,end)constformData=newFormData()formData.append('fileId',fileId)formData.append('chunkIndex',i)formData.append('totalChunks',chunks)formData.append('chunkData',chunk)formData.append('fileName',file.name)formData.append('relativePath',file.relativePath||'')// 保留层级try{awaitaxios.post('/api/upload/chunk',formData,{onUploadProgress:(e)=>{this.updateProgress(fileId,i,chunks,e.loaded)}})}catch(e){console.error(`分片${i}上传失败`,e)throwe}}// 通知服务器合并分片awaitaxios.post('/api/upload/merge',{fileId,fileName:file.name})}}}关键点:
webkitdirectory属性(Chrome/Edge)// Controllers/UploadController.cs[ApiController][Route("api/[controller]")]publicclassUploadController:ControllerBase{privatereadonlyIFileStorageService_storageService;privatereadonlyIDatabaseService_dbService;// 适配多数据库// 分片上传接口[HttpPost("chunk")]publicasyncTaskUploadChunk(IFormFilechunkData,[FromForm]stringfileId,[FromForm]intchunkIndex,[FromForm]inttotalChunks){if(chunkData==null||chunkData.Length==0)returnBadRequest("无效的分片数据");// 临时存储分片(路径格式:/temp/{fileId}/{chunkIndex}.part)vartempPath=Path.Combine("temp",fileId,$"{chunkIndex}.part");Directory.CreateDirectory(Path.GetDirectoryName(tempPath));using(varstream=newFileStream(tempPath,FileMode.Create)){awaitchunkData.CopyToAsync(stream);}// 记录分片信息到数据库(达梦/人大金仓兼容)await_dbService.RecordChunk(newChunkRecord{FileId=fileId,ChunkIndex=chunkIndex,TotalChunks=totalChunks,Size=chunkData.Length,ReceivedTime=DateTime.Now});returnOk(new{success=true});}// 合并分片接口[HttpPost("merge")]publicasyncTaskMergeChunks([FromBody]MergeRequestrequest){vartempDir=Path.Combine("temp",request.FileId);if(!Directory.Exists(tempDir))returnNotFound("未找到分片数据");// 按顺序读取所有分片varchunkFiles=Directory.GetFiles(tempDir,"*.part").OrderBy(f=>int.Parse(Path.GetFileNameWithoutExtension(f))).ToList();// 最终存储路径(保留原始相对路径)varfinalPath=Path.Combine("uploads",request.RelativePath,request.FileName);Directory.CreateDirectory(Path.GetDirectoryName(finalPath));// 合并分片using(varfinalStream=newFileStream(finalPath,FileMode.Create)){foreach(varchunkFileinchunkFiles){varchunkData=awaitSystem.IO.File.ReadAllBytesAsync(chunkFile);awaitfinalStream.WriteAsync(chunkData,0,chunkData.Length);System.IO.File.Delete(chunkFile);// 删除临时分片}}// 清理空目录Directory.Delete(tempDir);// 记录完整文件信息到数据库await_dbService.RecordFinalFile(newFinalFileRecord{FileId=request.FileId,FilePath=finalPath,Size=newFileInfo(finalPath).Length,UploadTime=DateTime.Now});returnOk(new{url=$"/downloads/{finalPath}"});}}// Services/IDatabaseService.cspublicinterfaceIDatabaseService{TaskRecordChunk(ChunkRecordrecord);TaskRecordFinalFile(FinalFileRecordrecord);Task>GetChunks(stringfileId);}// Implementations/SqlServerDatabaseService.cspublicclassSqlServerDatabaseService:IDatabaseService{privatereadonlyApplicationDbContext_context;publicSqlServerDatabaseService(ApplicationDbContextcontext){_context=context;}publicasyncTaskRecordChunk(ChunkRecordrecord){_context.Chunks.Add(record);await_context.SaveChangesAsync();}// 其他方法实现...}// Implementations/DamengDatabaseService.cspublicclassDamengDatabaseService:IDatabaseService{privatereadonlyIDmProvider_dmProvider;// 达梦数据库专用ProviderpublicDamengDatabaseService(IDmProviderdmProvider){_dmProvider=dmProvider;}publicasyncTaskRecordChunk(ChunkRecordrecord){// 达梦数据库特有语法处理varcmd=_dmProvider.CreateCommand();cmd.CommandText="INSERT INTO CHUNK_RECORDS VALUES(...)";// ...参数绑定awaitcmd.ExecuteNonQueryAsync();}}关键设计:
/temp/{fileId}/{index}.part组织// Program.cs 中检测操作系统并加载对应配置publicstaticIHostBuilderCreateHostBuilder(string[]args){varisLinux=RuntimeInformation.IsOSPlatform(OSPlatform.Linux);varisKylin=File.Exists("/etc/kylin-release");// 银河麒麟检测varisUOS=File.Exists("/etc/uos-release");// 统信UOS检测returnHost.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder=>{webBuilder.UseStartup();if(isKylin||isUOS){webBuilder.UseKestrel(options=>{options.ListenAnyIP(5000,listenOptions=>{listenOptions.Protocols=HttpProtocols.Http1AndHttp2;});});}});}// src/utils/browserDetect.jsexportfunctiondetectBrowser(){constua=navigator.userAgentif(ua.includes('LongArch'))return'longxin'// 龙芯浏览器if(ua.includes('RedLotus'))return'redlotus'// 红莲花浏览器if(ua.includes('QiAnXin'))return'qianxin'// 奇安信浏览器if(ua.includes('MSIE 8')||ua.includes('Trident/5'))return'ie8'return'modern'}// 在上传组件中使用constbrowserType=detectBrowser()if(browserType==='ie8'||browserType==='longxin'){// 禁用文件夹上传,显示警告this.$message.warning('当前浏览器仅支持单文件上传')}结语:
在信创环境下开发大文件传输系统,就像在"带着镣铐跳舞"。但通过合理的架构设计和兼容性处理,我们最终交付了满足政府需求的稳定方案。完整代码已开源至内部GitLab(因涉密需申请访问),欢迎同行交流(可加QQ群:374992201)。
(完)
——北京政府项目组·张工
安装.NET Framework 4.7.2
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472
框架选择4.7.2
NOSQL无需任何配置可直接访问页面进行测试
使用IIS
大文件上传测试推荐使用IIS以获取更高性能。
小文件上传测试可以使用IIS Express
相关参考:
文件保存位置,
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。
支持文件批量下载
文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。
支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。
下载完整示例