BigFileUploader(JS分片上传)

简介大文件的上传是我一直以来想学习的一个技术点,今天在项目闲暇之时,终于有机会自己尝试了一把,本文仅仅是个Demo,各种错误处理都么有,仅限于大家来学习思路。

一、开始

  • 作为一个Demo,肯定是得先新建项目啦~笔者在这里使用的是VS 2012,所以只能新建MVC 4的项目

  • 项目新建好之后,从官网下载WebUploader的包 http://fex.baidu.com/webuploader/download.html

  • 在Index.cshtml中引入Jquery、webuploader.css、webuploader.js

  • 照着官网的Getting Started 里面的例子,初始化WebUploader,这里不再详细描述

  • 初始化的时候,有几个参数需要特别处理,看我的初始化参数

     1 var GUID = WebUploader.Base.guid();//一个GUID 2     var uploader = WebUploader.create({ 3         swf: '/Scripts/Plugins/webuploader-0.1.5/Uploader.swf', 4         server: '@Url.Action("Upload")', 5         pick: '#picker', 6         resize: false, 7         chunked: true,//开始分片上传 8         chunkSize: 2048000,//每一片的大小 9         formData: {10             guid: GUID //自定义参数,待会儿解释11         }12     });

二、前端准备上传分片

给开始上传按钮绑定上一个Click事件,来调用WebUploader的upload事件,如果你开启了自动上传,可以省略这一步。这样子,点了按钮就会开始上传工作,WebUploader就会自动把文件分片分好,然后上传到服务器端。

1 $("#ctlBtn").click(function () {2         uploader.upload();3   });

 

三、后端接收上传文件

开始之前,先说一下基本的思路:

在特定的上传目录下面,先根据前端传过来的GUID创建一个临时的目录,然后接受分块,把所有的分块分别保存起来,上传完成之后合并这些分块。

好了,开始上代码:

 1 [HttpPost] 2 public ActionResult Upload() 3 { 4     string fileName = Request["name"]; 5     int index = Convert.ToInt32(Request["chunk"]);//当前分块序号 6     var guid = Request["guid"];//前端传来的GUID号 7     var dir = Server.MapPath("~/Upload");//文件上传目录 8     dir = Path.Combine(dir, guid);//临时保存分块的目录 9     if (!System.IO.Directory.Exists(dir))10         System.IO.Directory.CreateDirectory(dir);11     string filePath = Path.Combine(dir, index.ToString());//分块文件名为索引名,更严谨一些可以加上是否存在的判断,防止多线程时并发冲突12     var data = Request.Files["file"];//表单中取得分块文件13     data.SaveAs(filePath);//保存14     return Json(new { erron = 0 });//Demo,随便返回了个值,请勿参考15 }

 

需要注明的是,分块的序号、文件名等,均可以在WebUploader上传过来的Request里面取到,除了我取到的这些值,还有最后修改日期,总共多少分块、文件总大小等,卡个断点一看便知。

四、上传完毕,合并文件,删除分片

由于WebUploader是多线程的上传,所以不一定文件块会按照顺序来到服务器,所以我原本打算在Upload中进行合并文件的想法泡汤了~当然,或许可以去判断当前文件夹中的文件数目等于分块数目这种方式来处理,但是总感觉不靠谱,万一当时只是把那个文件创建出来了,内容还没写进去怎么办?大家有更好的思路,欢迎探讨~

我目前的做法,是通过WebUploader的uploadSuccess来手动出发合并文件,Js代码如下:

1  uploader.on('uploadSuccess', function (file,response) {2         $.post('@Url.Action("Merge")', { guid: GUID, fileName: file.name }, function (data) {3             $list.text('已上传');4         });5         6     });

 

当前端判断说所有分片上传成功的时候,去调用后端接口,告诉他GUID和文件名称(有文件的格式就好了,不然没法正确存储),后端合并代码如下:

 1 public ActionResult Merge() 2 { 3     var guid = Request["guid"];//GUID 4     var uploadDir = Server.MapPath("~/Upload");//Upload 文件夹 5     var dir = Path.Combine(uploadDir, guid);//临时文件夹 6     var fileName = Request["fileName"];//文件名 7     var files = System.IO.Directory.GetFiles(dir);//获得下面的所有文件 8     var finalPath = Path.Combine(uploadDir, fileName);//最终的文件名(demo中保存的是它上传时候的文件名,实际操作肯定不能这样) 9     var fs = new FileStream(finalPath, FileMode.Create);10     foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序,保证从0-N Write11     {12         var bytes = System.IO.File.ReadAllBytes(part);13         fs.Write(bytes, 0, bytes.Length);14         bytes = null;15         System.IO.File.Delete(part);//删除分块16     }17     fs.Close();18     System.IO.Directory.Delete(dir);//删除文件夹19     return Json(new { error = 0 });//随便返回个值,实际中根据需要返回20 }

 

五、整体代码送上

2016年6月12日更新:加入暂停功能,加入进度条。

前端:

index.cshtml

后端:

HomeController.cs

如果有什么不足或您有更好的想法,欢迎评论探讨~

错误修正:

感谢网友@豬豬→小熊 反馈的文件合并后打开错误的问题,经过查看我在文件合并时所用的files.OrderBy(x=>x)不可行,因为在当文件从小到大时,字符串的排序并不会按照数字的排序去排,举个例子:从0到1000,字符串排序的结果出来会是:0,1,10,100,1000,101,10001,因为他是从第一位开始比较的,2的第一位比11的第一位1大,所以11会排在2前面,所以应该将此排序改为:files.OrderBy(x => x.Length).ThenBy(x => x),这段代码的含义是:长度小的排在前面,如果长度一样,则按字符串从小到大排列,这样子就能保证文件在合并时的排序正确,并保证最终合并完成能够打开。

Github:https://github.com/ODotNet/BigFileUploader

欢迎Pull你对此Demo的改进~



https://github.com/ODotNet/BigFileUploader



声明:
1,如果您发现本文件已经失效不能下载,请联系站长修正或留言!
2,本站提供的资源多数为百度网盘下载,对于大文件,你需要安装百度云客户端才能下载!
3,部分文件引用的官方或者非网盘类他站下载链接,你可能需要使用迅雷、BT等下载工具下载!
4,本站推荐的资源均经由站长检测或者个人发布,不包含恶意软件病毒代码等,如果你发现此类问题,请向站长举报!
5,本站仅提供文件的免费下载服务,如果你对代码程序软件的使用有任何疑惑,请留言。
6,本网站在文章内容仅供于学习参考使用,请勿作为商业通途使用,版权归原作者所有。如您对内容、版权等问题存在异议请与本站联系,我们会及时进行处理解决。

下一篇:

tp5写分页内容会重置怎么办?


上一篇:

Navicat


文章评论

Top