网站改版需要注意,如何判断网站是否被k,龙岩网上房地产网,三维免费网站(给DotNet加星标#xff0c;提升.Net技能)转自#xff1a;学习中的苦与乐cnblogs.com/xiongze520/p/10412693.html现在的项目开发基本上都用到了上传文件功能#xff0c;或图片#xff0c;或文档#xff0c;或视频。我们常用的常规上传已经能够满足当前要求了#xff0c;… (给DotNet加星标提升.Net技能)转自学习中的苦与乐cnblogs.com/xiongze520/p/10412693.html现在的项目开发基本上都用到了上传文件功能或图片或文档或视频。我们常用的常规上传已经能够满足当前要求了然而有时会出现如下问题文件过大(比如1G以上)超出服务端的请求大小限制请求时间过长请求超时传输中断必须重新上传导致前功尽弃设置了webconfig和iis后还是不能上传成功不想使用FTP只想用http。我们这里只讲分片上传至于断网续传和秒传已经写好Demo下载地址放在文末有兴趣的可以下载自己玩玩。分片上传demo下载地址https://pan.baidu.com/s/1osGyv2qYzTmtNIImqkcKvw 提取码ie57分片上传、断网续传、秒传demo下载地址https://pan.baidu.com/s/1TuvGR6qUcKLMFjZGaQl5vg 提取码aej4http的网络请求中本身就已经具备了分片上传功能那么什么是分片上传我们来看看分片上传原理片上传支持将一个文件切割为一系列特定大小的数据片分别将这些小数据片上传到服务端全部上传完后再在服务端将这些数据片合并成为一个资源。分片上传引入了两个概念块(Block)和片(Chunk)。每个块由一到多个片组成而一个资源则由一到多个块组成。他们之间的关系可以用下图表述块和片是上传过程中作为临时存储的单位。服务端会以约七天为单位的周期清除上传后未被合并为块(文件)的数据片(块)。与分片上传相关的 API 有创建块(mkblk)、上传片(bput)、创建文件(mkfile)。一个完整的分片上传流程可用下图表示其中的关键点如下将待上传的文件按预定义块大小切分为若干个块(每块大小不大于 4MB块的大小可以自定义)。如果这个文件小于 4MB就只有一个块。将每个块再按预定义的片大小切分为若干个片先在服务端创建一个相应块(通过调用mkblk并带上第一个片的内容)然后再循环将所有剩下的片全部上传(通过调用bput从而完成一个块的上传)在所有块上传完成后通过调用mkfile将这些上传完成的块信息再严格的按顺序组装出一个逻辑资源的元信息从而完成整个资源的分片上传过程。在这个理论基础上结合WebUploade插件(百度上传插件)和net mvc进行demo编写老规矩demo在文末可以下载。我们看一下效果图分片上传上传中(图一)上传成功(图二)分片、断网(暂停)、秒传上传中(图一)上传成功(图二)代码展示下载webuploader插件后引入项目中主要引用文件script src~/Scripts/jquery-1.10.2.min.jsscriptlink href~/Content/webuploader.css relstylesheet /script src~/Scripts/webuploader.jsscriptscript src~/Scripts/bootstrap.min.jsscript前端完整代码html xmlnshttp://www.w3.org/1999/xhtmlheadmeta http-equivContent-Type contenttext/html; charsetutf-8 /titletitleheadbodyscript src~/Scripts/jquery-1.10.2.min.jsscriptlink href~/Content/webuploader.css relstylesheet /script src~/Scripts/webuploader.jsscriptscript src~/Scripts/bootstrap.min.jsscriptdiv iduploader classwu-examplediv idthelist classuploader-listdivdiv classbtnsdiv idpicker选择文件divinput idctlBtn typebutton value开始上传 classbtn btn-default /divdivtable width50% border1 classfileList_parenttheadtr stylebackground-color:#DADADAth文件名称thth类型thth大小thth进度thth说明thtrtheadtbody classfileListtbodytablebodyhtmlscriptvar applicationPath window.applicationPath ? : window.applicationPath || ../../;var GUID WebUploader.Base.guid();//一个GUID $(function () {var $ jQuery;var $list $(#thelist);var uploader WebUploader.create({// 选完文件后是否自动上传。 auto: false,// swf文件路径 swf: applicationPath ../Content/Uploader.swf,// 文件接收服务端。 server: applicationPath Home/Upload,// 选择文件的按钮。可选。// 内部根据当前运行是创建可能是input元素也可能是flash. pick: #picker,chunked: true,//开始分片上传 chunkSize: 2048000,//每一片的大小 formData: {guid: GUID //自定义参数待会儿解释 },// 不压缩image, 默认如果是jpeg文件上传前会压缩一把再上传 resize: false });// 当有文件被添加进队列的时候 uploader.on(fileQueued, function (file) { $list.append( file.name 等待上传... );var name file.name; //文件名var type fileType(file.name); //文件类型获取的是文件的后缀var volume bytesToSize(file.size); //文件大小格式化var oTr $();var str name name ; str type ; str volume ; str ; str 0%; str ; str 等待上传; $(.fileList).html(str) }); var aa 1; // 文件上传过程中创建进度条实时显示。 uploader.on(uploadProgress, function (file, percentage) { var $li $(# file.id), $percent $li.find(.progress .progress-bar); // 避免重复创建 if (!$percent.length) { $percent $( ).appendTo($li).find(.progress-bar); } $li.find(p.state).text(上传中); $(#uploding).html(上传中); $percent.css(width, percentage * 100 %); if (percentage 1) { aa; } if (aa2) { var shuzipercentage * 100; $(#baifenbi).html(shuzi.toFixed(2)); } }); // 文件上传成功给item添加成功class, 用样式标记上传成功。 uploader.on(uploadSuccess, function (file, response) { $(# file.id).find(p.state).text(已上传); $.post(Home/Merge, { guid: GUID, fileName: file.name }, function (data) { $(#uploader .state).html(上传成功...); $(#uploding).html(上传成功); }); }); // 文件上传失败显示上传出错。 uploader.on(uploadError, function (file) { $(# file.id).find(p.state).text(上传出错); }); // 完成上传完了成功或者失败先删除进度条。 uploader.on(uploadComplete, function (file) { $(# file.id).find(.progress).fadeOut(); }); //所有文件上传完毕 uploader.on(uploadFinished, function () { //提交表单 }); //开始上传 $(#ctlBtn).click(function () { uploader.upload(); }); }); //字节大小转换参数为b function bytesToSize(bytes) { var sizes [Bytes, KB, MB, G]; if (bytes 0) return n/a; var i parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); return (bytes / Math.pow(1024, i)).toFixed(1) sizes[i]; }; //通过文件名返回文件的后缀名 function fileType(name) { var nameArr name.split(.); return nameArr[nameArr.length - 1].toLowerCase(); }script后端控制器完整代码展示using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Web;using System.Web.Mvc;namespace BigFileUploader.Controllers{ public class HomeController : Controller { #region 文件上传 [HttpPost] public ActionResult Upload(){ string fileName Request[name]; string fileRelName fileName.Substring(0, fileName.LastIndexOf(.));//设置临时存放文件夹名称 int index Convert.ToInt32(Request[chunk]);//当前分块序号 var guid Request[guid];//前端传来的GUID号 var dir Server.MapPath(~/Upload);//文件上传目录 dir Path.Combine(dir, fileRelName);//临时保存分块的目录 if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir); string filePath Path.Combine(dir, index.ToString());//分块文件名为索引名更严谨一些可以加上是否存在的判断防止多线程时并发冲突 var data Request.Files[file];//表单中取得分块文件 string extension data.FileName.Substring(data.FileName.LastIndexOf(.) 1, (data.FileName.Length - data.FileName.LastIndexOf(.) - 1));//获取文件扩展名 //if (data ! null)//为null可能是暂停的那一瞬间 //{ data.SaveAs(filePath fileName); //} return Json(new { erron 0 });//Demo随便返回了个值请勿参考 } public ActionResult Merge(){ var guid Request[guid];//GUID var uploadDir Server.MapPath(~/Upload);//Upload 文件夹 var fileName Request[fileName];//文件名 string fileRelName fileName.Substring(0, fileName.LastIndexOf(.)); var dir Path.Combine(uploadDir, fileRelName);//临时文件夹 var files System.IO.Directory.GetFiles(dir);//获得下面的所有文件 var finalPath Path.Combine(uploadDir, fileName);//最终的文件名(demo中保存的是它上传时候的文件名实际操作肯定不能这样) var fs new FileStream(finalPath, FileMode.Create); foreach (var part in files.OrderBy(x x.Length).ThenBy(x x))//排一下序保证从0-N Write { var bytes System.IO.File.ReadAllBytes(part); fs.Write(bytes, 0, bytes.Length); bytes null; System.IO.File.Delete(part);//删除分块 } fs.Flush(); fs.Close(); System.IO.Directory.Delete(dir);//删除文件夹 return Json(new { error 0 });//随便返回个值实际中根据需要返回 } #endregion }}总结以上说的是分片上传的demo断网续传和秒传在下面大家下载下来玩哇个人感觉蛮不错的。我一直都主张功能点先写Demo有了成功的Demo后引入项目中Demo可以存储起来做知识储备保不定哪天又用到了。推荐阅读(点击标题可跳转阅读)一键部署VS插件让.NET开发者更幸福.NET Core In Docker内编译发布并运行ASP.NET Core 部署到 IIS 进行托管看完本文有收获请转发分享给更多人关注「DotNet」加星标提升.Net技能 喜欢就点一下「好看」呗~