首页 > 其他分享 >.Net Core MVC超大文件上传

.Net Core MVC超大文件上传

时间:2023-11-23 21:55:49浏览次数:31  
标签:Core false val chunk fileName MVC var Net chunkIndex

后端控制器:
//用于保存的文件夹 static readonly string uploadFolder = "UploadFolder"; //目录分隔符,兼容不同系统 static readonly char dirSeparator = Path.DirectorySeparatorChar; string GetTmpChunkDir(string fileName) => HttpContext.Session.TryGetValue(fileName, out byte[] bytes) ? Encoding.Default.GetString(bytes) : ""; //[UnifyResult(typeof(JsonResult))] //保存文件 [HttpPost] public async Task<JsonResult> SaveChunkFile(IFormFile chunk, string fileName, int chunkIndex, int chunkCount) { try { if (chunk.Length == 0) { return Json(new { success = false, msg = "File Length 0", }); } if (chunkIndex == 0) { //第一次上传时,生成一个随机id,做为保存块的临时文件夹,记录到session HttpContext.Session.Set(fileName, Encoding.Default.GetBytes(Guid.NewGuid().ToString("N"))); } if (!Directory.Exists(uploadFolder)) Directory.CreateDirectory(uploadFolder); var fullChunkDir = uploadFolder + dirSeparator + GetTmpChunkDir(fileName); if (!Directory.Exists(fullChunkDir)) Directory.CreateDirectory(fullChunkDir); var blob = chunk.FileName; var newFileName = blob + chunkIndex + Path.GetExtension(fileName); var filePath = fullChunkDir + Path.DirectorySeparatorChar + newFileName; //保存文件块 using (var stream = new FileStream(filePath, FileMode.Create)) { await chunk.CopyToAsync(stream); } //所有块上传完成 if (chunkIndex == chunkCount - 1) { //也可以在这合并,在这合并就不用ajax调用CombineChunkFile合并 //CombineChunkFile(fileName); } var obj = new { success = true, date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), newFileName, originalFileName = fileName, size = chunk.Length, nextIndex = chunkIndex + 1, }; return Json(obj); } catch (Exception ex) { return Json(new { success = false, msg = ex.Message, }); } } [UnifyResult(typeof(JsonResult))] //合并文件 public async Task<JsonResult> CombineChunkFile(string fileName) { try { return await Task.Run(() => { var tmpDir = GetTmpChunkDir(fileName); var fullChunkDir = uploadFolder + dirSeparator + tmpDir; var beginTime = DateTime.Now; var newFileName = tmpDir + Path.GetExtension(fileName); var destFile = uploadFolder + dirSeparator + newFileName; //获取临时文件夹内的所有文件块,排好序 var files = Directory.GetFiles(fullChunkDir).OrderBy(x => x.Length).ThenBy(x => x).ToList(); using (var destStream = System.IO.File.OpenWrite(destFile)) { files.ForEach(chunk => { using (var chunkStream = System.IO.File.OpenRead(chunk)) { chunkStream.CopyTo(destStream); } System.IO.File.Delete(chunk); }); Directory.Delete(fullChunkDir); } var totalTime = DateTime.Now.Subtract(beginTime).TotalSeconds; return Json(new { success = true, destFile = destFile.Replace('\\', '/'), msg = $"combine completed ! {totalTime} s", }); }); } catch (Exception ex) { return Json(new { success = false, msg = ex.Message, }); } finally { HttpContext.Session.Remove(fileName); } }
本人用的百小僧MVC框架
前端视图代码:

@{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <div> <input type="file" id="file1" value="" /> <input type="button" id="btnUplaod" value="Upload" multiple="multiple" /> </div> <div id="completedChunks"></div> <div id="percent">0%</div> <div id="progress" style="width:200px;height:10px;background:linear-gradient(45deg, #ff0084 0%, #e8c5d7 0%);"></div> @section Scripts{ <script src="~/lib/vue/axios.min.js"></script> <script> //important //slice()函数要IE10+才支持。 //Firefox 12及更早版本的使用mozSlice() //Safari使用webkitSlice() $(function () { { var pause = false;//是否暂停 var $file; var $fileInput;//file input var $completedChunks = $('#completedChunks');//上传完成块数 var $progress = $('#progress');//上传进度条 var $percent = $('#percent');//上传百分比 var MiB = 1024 * 1024; var chunkSize = 8.56 * MiB;//xx MiB var chunkIndex = 0;//上传到的块 var $btnUpload = $('#btnUplaod'); var totalSize;//文件总大小 var totalSizeH;//文件总大小M var chunkCount;//分块数 var fileName;//文件名 $btnUpload.click(function () { var val = $.trim($(this).val()); if (val === 'Upload') { $fileInput = $('#file1'); $file = $fileInput[0].files[0]; if ($file === undefined) { $completedChunks.html('please select a file !'); return false; } totalSize = $file.size; chunkCount = Math.ceil(totalSize / chunkSize * 1.0); totalSizeH = (totalSize / MiB).toFixed(2); fileName = $file.name; val = 'Pause'; pause = false; chunkIndex = 0; } else if (val === 'Pause') { val = 'Resume'; pause = true; } else if (val === 'Resume') { val = 'Pause'; pause = false; } else { val = '-'; } $(this).val(val); postChunk(); }); function postChunk() { if (pause) return false; var isLastChunk = chunkIndex === chunkCount - 1; var fromSize = chunkIndex * chunkSize; var chunk = !isLastChunk ? $file.slice(fromSize, fromSize + chunkSize) : $file.slice(fromSize, totalSize); var fd = new FormData(); fd.append('chunk', chunk); fd.append('chunkIndex', chunkIndex); fd.append('chunkCount', chunkCount); fd.append('fileName', fileName); fd.append('__RequestVerificationToken', $("input[name=__RequestVerificationToken]").val()); $.ajax({ url: '/HtAdmin/Upload/SaveChunkFile', type: 'POST', data: fd, cache: false, contentType: false, processData: false, success: function (d) { if (!d.success) { $completedChunks.html(d.msg); return false; } chunkIndex = d.nextIndex; if (isLastChunk) { $completedChunks.html('combining .. '); $btnUpload.val('Upload').prop('disabled', true); //合并文件 $.post('/HtAdmin/Upload/CombineChunkFile', { fileName: fileName }, function (d) { $completedChunks.html(d.msg); $completedChunks.append('destFile: ' + d.destFile); $btnUpload.val('Upload').prop('disabled', false); $fileInput.val('');//清除文件 }); } else { postChunk();//递归上传文件块 //$completedChunks.html(chunkIndex + '/' + chunkCount ); $completedChunks.html((chunkIndex * chunkSize / MiB).toFixed(2) + 'M/' + totalSizeH + 'M'); } var completed = chunkIndex / chunkCount * 100; $percent.html(completed.toFixed(2) + '%').css('margin-left', parseInt(completed / 100 * $progress.width()) + 'px'); $progress.css('background', 'linear-gradient(to right, #ff0084 ' + completed + '%, #e8c5d7 ' + completed + '%)'); }, error: function (ex) { $completedChunks.html('ex:' + ex.responseText); } }); } } }); </script> } </div>

 

 

标签:Core,false,val,chunk,fileName,MVC,var,Net,chunkIndex
From: https://www.cnblogs.com/m0616/p/17852579.html

相关文章

  • netty服务端加解密
    参考链接:https://www.cnblogs.com/silyvin/articles/11827030.html一、解密1、自定义解密类importio.netty.buffer.ByteBuf;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelHandlerContext;importio.netty.handler.codec.ByteToMessageDecoder;impor......
  • netcore 同步方法里调异步,异步方法里调用同步,不死锁写法
     ///<summary>///同步方法里调用异步///</summary>staticvoidSyncMethod(){//同步方法中调用异步方法(第一种写法)AsyncMethod(参数1,参数2).ConfigureAwait(false).GetAwaiter().GetResult();//同步方法中调用异步方法(第二种写法)AsyncHelper.RunSync......
  • 使用EF8在Core8中出现的奇葩bug
    1.add-migrationaddtable 一切正常  2.在update-database-verbose出现奇葩bug System.Globalization.CultureNotFoundException:Onlytheinvariantcultureissupportedinglobalization-invariantmode.Seehttps://aka.ms/GlobalizationInvariantModeformore......
  • Kubernetes进阶之使用二进制包部署集群
    前言之前关于Kubernetes有写过文档参考:Kubernetes入门进阶课程https://www.cnblogs.com/minseo/category/1654539.html本文针对操作系统以及软件的新版本补充使用二进制包部署集群之前版本部署参考:https://www.cnblogs.com/minseo/p/12361731.html......
  • Firefox developer tools truncates long network response, Chrome does not show
    Firefoxdevelopertoolstruncateslongnetworkresponse,ChromedoesnotshowFirefoxdevtoolsnetworkinspectorstilltruncatesresponsesto1MBbydefault.Youcanchangeordisablethelimitbynavigatingtoabout:configandchangingdevtools.netmonit......
  • 通过Spring MVC 实现 Restful 风格请求⽀持
     通过SpringMVC可以很方便地实现Restful风格的请求支持。Restful风格的请求是一种基于HTTP协议的轻量级的Web服务架构风格,它通过HTTP的GET、POST、PUT、DELETE等方法来实现对资源的增删改查操作。在SpringMVC中,我们可以使用注解来定义Restful风格的请求处理方法,并且可以方便......
  • Convolutional Neural Networks on Graphs with Chebyshev Approximation, Revisited
    目录概符号说明MotivationChebNetII代码HeM.,WeiZ.andWenJ.Convolutionalneuralnetworksongraphswithchebyshevapproximation,revisited.NIPS,2022.概作者剖析了ChebNet存在的一些缺陷,并通过约束系数获得更好的性能.符号说明\(V\),nodeset;\(E\),......
  • Linux安装dotnet运行时
    CentosLinux安装.NET之前,请运行以下命令,将Microsoft包签名密钥添加到受信任密钥列表,并添加Microsoft包存储库。打开终端并运行以下命令:sudorpm-Uvhhttps://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm查找可安装包yumlistdotnet*安装SDK.NET......
  • 【Kubernetes】 容器探针
    【Kubernetes】容器探针Kubernetes提供了探针,通过Kubelet对容器执行定期诊断,以了解容器内应用的状态,以探测结果来决定做哪些操作(比如重启容器、关闭流量),kubernetes中提供了三种探针,分别是就绪探针、存活探针、启动探针,如果不使用探针,默认认为是成功的。每种探针又提供了四种探......
  • DEVICENET 从站转 MODBUS-TCP 网关操作案例
    兴达易控DEVICENET从站转MODBUS-TCP网关操作案例兴达易控DEVICENET从站转MODBUS-TCP网关(XD-ETHDE20)是一款DEVICENET从站功能的通讯网关。该产品主要功能是将DEVICENET总线和MODBUS-TCP网络连接起来。兴达易控DEVICENET从站转MODBUS-TCP网关连接到DEVICENET总......