Z世代视角解构藏地青春 《一个夜晚与三个夏天》定档10月13日
2026/10/2 12:35:35
大家好,我是福州某校软件工程专业的大三狗,眼看毕业季来临,我决定做个"惊天地泣鬼神"的文件管理系统当毕业设计(主要是为了找工作时有东西可以吹)。
// 大文件分片上传(10G?先试试10M吧)classBigFileUploader{constructor(){this.chunkSize=5*1024*1024;// 5MB一片this.retryCount=3;this.queue=[];this.paused=false;}// 选择文件后的处理handleFileSelect(e){constfile=e.target.files[0];if(!file){alert('老板,您倒是选个文件啊!');return;}if(file.size>10*1024*1024*1024){alert('10G?您电脑内存够吗?');return;}this.sliceAndUpload(file);}// 文件分片sliceAndUpload(file){consttotalChunks=Math.ceil(file.size/this.chunkSize);letuploadedChunks=this.loadProgress(file.name)||0;for(leti=uploadedChunks;i<totalChunks;i++){conststart=i*this.chunkSize;constend=Math.min(file.size,start+this.chunkSize);constchunk=file.slice(start,end);this.queue.push({chunk,chunkNumber:i,totalChunks,fileName:file.name,fileSize:file.size,retry:0});}this.processQueue();}// 上传队列处理processQueue(){if(this.paused||this.queue.length===0)return;constitem=this.queue.shift();this.uploadChunk(item).then(()=>{this.saveProgress(item.fileName,item.chunkNumber+1);this.processQueue();}).catch(err=>{console.error('上传失败:',err);if(item.retry<this.retryCount){item.retry++;this.queue.unshift(item);setTimeout(()=>this.processQueue(),1000);}else{alert(`文件${item.fileName}第${item.chunkNumber+1}片上传失败!`);}});}// 实际分片上传uploadChunk(item){returnnewPromise((resolve,reject)=>{constformData=newFormData();formData.append('file',item.chunk);formData.append('chunkNumber',item.chunkNumber);formData.append('totalChunks',item.totalChunks);formData.append('fileName',item.fileName);// 这里应该加上加密逻辑(但我还没学会)constxhr=newXMLHttpRequest();xhr.open('POST','/api/upload',true);xhr.onload=()=>{if(xhr.status===200){resolve(JSON.parse(xhr.responseText));}else{reject(newError('上传失败: '+xhr.statusText));}};xhr.onerror=()=>reject(newError('网络错误'));xhr.send(formData);});}// 保存进度到localStorage(不够持久?)saveProgress(fileName,uploadedChunks){constprogress=JSON.parse(localStorage.getItem('uploadProgress')||'{}');progress[fileName]=uploadedChunks;localStorage.setItem('uploadProgress',JSON.stringify(progress));}// 加载进度loadProgress(fileName){constprogress=JSON.parse(localStorage.getItem('uploadProgress')||'{}');returnprogress[fileName]||0;}}@RestController@RequestMapping("/api")publicclassFileUploadController{@Value("${upload.dir}")privateStringuploadDir;@PostMapping("/upload")publicResponseEntityuploadChunk(@RequestParam("file")MultipartFilefile,@RequestParam("chunkNumber")intchunkNumber,@RequestParam("totalChunks")inttotalChunks,@RequestParam("fileName")StringfileName){try{// 创建临时目录StringtempDir=uploadDir+File.separator+"temp_"+fileName;Filedir=newFile(tempDir);if(!dir.exists()){dir.mkdirs();}// 保存分片文件StringchunkName=chunkNumber+".part";FilechunkFile=newFile(dir,chunkName);file.transferTo(chunkFile);// 如果是最后一片,合并文件if(chunkNumber==totalChunks-1){mergeFiles(fileName,tempDir,totalChunks);}returnResponseEntity.ok().body(Map.of("success",true,"message","分片上传成功","chunkNumber",chunkNumber));}catch(Exceptione){returnResponseEntity.status(500).body(Map.of("success",false,"message","分片上传失败: "+e.getMessage()));}}privatevoidmergeFiles(StringfileName,StringtempDir,inttotalChunks)throwsIOException{FileoutputFile=newFile(uploadDir,fileName);try(FileOutputStreamfos=newFileOutputStream(outputFile,true);BufferedOutputStreambos=newBufferedOutputStream(fos)){for(inti=0;i<totalChunks;i++){FilechunkFile=newFile(tempDir,i+".part");try(FileInputStreamfis=newFileInputStream(chunkFile);BufferedInputStreambis=newBufferedInputStream(fis)){byte[]buffer=newbyte[1024];intlen;while((len=bis.read(buffer))>0){bos.write(buffer,0,len);}}chunkFile.delete();// 删除已合并的分片}}// 删除临时目录newFile(tempDir).delete();}}有没有大神能:
欢迎加QQ群374992201交流!新人加群送红包!(虽然可能就1块钱)
找工作求带!
有师兄师姐在招人的吗?我要求不高:
(附上我的专业技能:会Google、会复制粘贴、会重启电脑)
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。
下载完整示例