700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 上传文件慢 SpringBoot分片上传文件

上传文件慢 SpringBoot分片上传文件

时间:2022-11-09 06:52:13

相关推荐

上传文件慢 SpringBoot分片上传文件

Java上传文件慢,大文件上传卡顿,请求超时怎么办?

话不多说直接上代码,代码复制过去可以直接使用

第一步:创建后端代码

package cn.leon.demo.rest;import lombok.extern.slf4j.Slf4j;import mons.io.FileUtils;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.FileOutputStream;import java.text.SimpleDateFormat;import java.util.Date;import java.util.UUID;/*** 分片上传文件相关接口** @author leon* @date /03/19 17:40:06*/@Slf4j@RequestMapping("/chunk-upload")@RestControllerpublic class UploadFileController {/*** 文件上传路径,配置文件配置或者这里写死也行* ##fileUploadPath* file.upload.path=/Users/leon/Desktop**/@Value("${file.upload.path}")private String fileUploadPath;/*** 分片上传小文件** @param clientId 客户端ID,每个客户端每次上传时生成,保持唯一* @param chunkId 分片ID,从0开始累加,每次上保持传唯一* @param chunks 分片总数* @param file* @return java.lang.String* @author leon* @date /04/07 17:16:59*/@CrossOrigin@PostMapping("/part")public Result bigFile(MultipartFile file, @RequestParam(name = "clientId", required = true) String clientId, @RequestParam(name = "chunks", required = true) Integer chunks, @RequestParam(name = "chunkId", required = true) Integer chunkId) throws Exception {log.info("开始上传分片文件,客户端ID:{},总分片数:{},分片ID:{}", clientId, chunks, chunkId);// 文件存放目录:临时目录用来存放所有分片文件SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");String dateStr = sdf.format(new Date());//临时文件目录String tempFileDir = fileUploadPath + File.separator + dateStr + clientId;File parentFileDir = new File(tempFileDir);if (!parentFileDir.exists()) {parentFileDir.mkdirs();}// 分片处理时,前台会多次调用上传接口,每次都会上传文件的一部分到后台File tempPartFile = new File(parentFileDir, clientId + "_" + chunkId + ".part");FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);log.info("分片文件上传成功,分片ID:{}", chunkId);return "ok";}/*** 上传分片文件完成后合并成一个大文件** @param clientId 客户端ID,每次上传时生成和分片上传时参数保持一致* @param fileName 原文件名* @return java.lang.String 返回最终保存文件路径* @author leon* @date /04/07 17:13:46*/@CrossOrigin@PostMapping("/merge")public String mergeFile(@RequestParam(name = "clientId", required = true) String clientId, @RequestParam(name = "fileName", required = true) String fileName) throws Exception {log.info("开始合并文件,客户端ID:{},文件名:{}", clientId, fileName);// 文件存放目录SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");String dateStr = sdf.format(new Date());//最终文件上传目录String fileSavePath = fileUploadPath + File.separator + dateStr;//临时文件目录String tmpFileSavePath = fileSavePath + clientId;//最终文件上传文件名String newFileName = UUID.randomUUID().toString();if (fileName.indexOf(".") != -1) {newFileName += fileName.substring(fileName.lastIndexOf("."));}//创建父文件夹File parentFileDir = new File(tmpFileSavePath);if (parentFileDir.isDirectory()) {File destNewFile = new File(fileSavePath, newFileName);if (!destNewFile.exists()) {//先得到文件的上级目录,并创建上级目录,再创建文件destNewFile.getParentFile().mkdir();destNewFile.createNewFile();}//遍历"所有分片文件"到"最终文件"中,此处一定要按照顺序合并文件,不然会导致文件合并错乱不可用for (int i=0;i<parentFileDir.listFiles().length;i++) {FileOutputStream destNewFileFos = new FileOutputStream(destNewFile, true);FileUtils.copyFile(new File(parentFileDir, clientId + "_" + i + ".part"), destNewFileFos);destNewFileFos.close();}// 删除临时目录中的分片文件FileUtils.deleteDirectory(parentFileDir);}log.info("合并文件完成,客户端ID:{},文件名:{}", clientId, fileName);return fileSavePath + newFileName;}}

第二步:创建前端代码测试

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head><title>分片上传文件测试</title><script src="/jquery/1.12.4/jquery.min.js"></script><meta content="text/html; charset=utf-8" http-equiv="Content-Type"/></head><body><div id="uploader"><div class="btns"><input id="file" name="file" type="file"/><br><br><button id="startBtn">开始上传</button></br></br></div><div id="output"></div></div></body><script type="text/javascript">var status = 0;//上传状态var startDate;var page = {init: function(){$("#startBtn").click($.proxy(this.upload, this));},upload: function(){startDate = (new Date()).getTime();console.log("开始上传文件......");status = 0;var clientId = this.generateClientId();var file = $("#file")[0].files[0], //文件对象fileName = file.name, //文件名size = file.size; //总大小var shardSize = 1024 * 1024, //以1MB为一个分片// var shardSize = 500 * 1024, //以500kb为一个分片shardCount = Math.ceil(size / shardSize); //总片数console.log("每个分片文件1MB,总分片数:"+shardCount);// console.log("每个分片文件500kb,总分片数:"+shardCount);for(var i = 0;i < shardCount;++i){//计算每一片的起始与结束位置var start = i * shardSize,end = Math.min(size, start + shardSize);var partFile = file.slice(start,end);this.partUpload(clientId,partFile,fileName,shardCount,i);console.log("第"+i+"个分片文件上传成功");}var endDate = (new Date()).getTime();console.log("所有分片文件上传请求发送成功,总耗时:"+(endDate-startDate)+"毫秒");},partUpload:function(clientId,partFile,fileName,chunks,chunkId){//构造一个表单,FormData是HTML5新增的var now = this;var form = new FormData();form.append("clientId", clientId);form.append("file", partFile); //slice方法用于切出文件的一部分form.append("fileName", fileName);form.append("chunks", chunks); //总片数form.append("chunkId", chunkId); //当前是第几片//Ajax提交$.ajax({url: "http://localhost:8080/chunk-upload/part",type: "POST",data: form,async: true, //异步processData: false, //很重要,告诉jquery不要对form进行处理contentType: false, //很重要,指定为false才能形成正确的Content-Typesuccess: function(data){status++;if(data.code == 0){$("#output").html(status+ " / " + chunks);}else{alert('出现异常:'+data.message);}if(status==chunks){var endDate = (new Date()).getTime();console.log("所有分片文件上传成功,总耗时:"+(endDate-startDate)+"毫秒")now.mergeFile(clientId,fileName);}}});},mergeFile:function(clientId,fileName){var formMerge = new FormData();formMerge.append("clientId", clientId);formMerge.append("fileName", fileName);$.ajax({url: "http://localhost:8080/chunk-upload/merge",type: "POST",data: formMerge,processData: false, //很重要,告诉jquery不要对form进行处理contentType: false, //很重要,指定为false才能形成正确的Content-Typessuccess: function(data){if(data.code == 0){var endDate = (new Date()).getTime();console.log("上传文件成功,总耗时:"+(endDate-startDate)+"毫秒");alert('上传成功!');}else{alert('出现异常:'+data.message);}}});},generateClientId:function(){var counter = 0;var clientId = (+new Date()).toString( 32 ),i = 0;for ( ; i < 5; i++ ) {clientId += Math.floor( Math.random() * 65535 ).toString( 32 );}return clientId + (counter++).toString( 32 );}};$(function(){page.init();});</script></html>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。