MVC模式实现WebUploader分段上传

前言

  基于.NET平台实现文件上传插件有很多种,jquery.upload.js、ajaxFileUpload.js、SWFUpload.js、WebUploader.JS。实际项目中配置简单,后期可维护性好的,建议采用ajaxFileUpload.js,缺点是上传文件功能单一,实现上传完成度显示需要集成UploadProcess.JS截获上传进度,且无法实现分段上传。WebUploader.js实现了所有的功能,且性能较优,下面介绍该空间实现分段上传及完成度显示实例。

配置

页面引用添加webuploader.css和webuploader.js,页面添加上传按钮元素,建议用div、p等换行标签,增加Id属性,页面添加结构如下:

参数index为自定义变量,保证当前页面存在多个上传按钮时便于区分。页面初始化定义代码如下:

uploadfilefun(o)为自定义封装JS函数;定义代码如下:

 1 //上传文档、视频
 2 function uploadfilefun(o) {
 3     var fb_ipt = $(o).find('.file-box >div').eq(0).attr('id');
 4     var guid = new GUID().newGuid();
 5     var uploader = WebUploader.create({
 6         auto: true,
 7         swf: '/Scripts/webuploader/Uploader.swf',
 8         server: '/superadmin/CourseSuper/ChunkUploadFile',
 9         pick: {
10             id: '#' + fb_ipt,
11             multiple: false
12         },
13         fileSingleSizeLimit: 500 * 1024 * 1024,   //设定单个文件大小(bit)
14         resize: false,
15         chunked: true,//分片上传-大文件的时候分片上传,默认false
16         chunkSize: 1024 * 1024,
17         formData: {
18             guid: guid//自定义参数
19         },
20         ///上传格式
21         accept: {
22             title: 'file limit',
23             extensions: 'xls,xlsx,doc,docx,ppt,pptx,pdf,mp4,swf,jpg,png',
24         }
25     })
26     var up_div = $(o).find('.upload');
27     var up_status = $(up_div).find('.upload-status');
28     uploader.on('uploadProgress', function (file, percentage) {
29         $(up_div).addClass('selected');
30         var nowSize = 0;//已上传大小
31         var gb = Math.pow(1024, 3);
32         var mb = Math.pow(1024, 2);
33         var kb = 1024;
34         var fileSize = uploader.getFiles()[uploader.getFiles().length - 1].size;//总大小
35         if (fileSize >= gb) {
36             Size = (fileSize / gb).toFixed(0) + "GB";
37         }
38         else if (fileSize >= mb) {
39             Size = (fileSize / mb).toFixed(0) + "MB";
40         }
41         else if (fileSize >= kb) {
42             Size = (fileSize / kb).toFixed(0) + "KB";
43         }
44         else {
45             Size = fileSize + "B";
46         }
47         $(up_status).addClass('i').removeClass('s f');
48         $(up_status).find('i').html((percentage * 100).toFixed(0) + "%");//已上传比例
49         $(up_div).find('.file-size').html("共" + Size);//总大小
50     });
51     uploader.on('uploadSuccess', function (file, response) {
52         $(up_div).find('input[name=Suffix]').val(response.Suffix);
53         var linkSelector = $(up_div).find('input[name=LinkResourceName]');
54         linkSelector.val(response.Name);
55         linkSelector.blur();
56         limitLinkResource(linkSelector, 30);
57         if (response.Status == 1) {
58             ///文件合并
59             $.post("/superadmin/coursesuper/merge", { "guid": guid, "suffix": response.Suffix }, function (data) {
60                 if (data.Status==1) {
61                     $(up_status).addClass('s').removeClass('i f');
62                     $(up_div).find('input[name=LinkResource]').val(data.fileGuid);
63                 }
64                 else {
65                     $(up_status).addClass('f').removeClass('i s');
66                 }
67             })
68         }
69         else {
70             $(up_status).addClass('f').removeClass('i s');
71         }
72         uploader.removeFile(file);
73         uploader.reset();
74     });
75 
76     uploader.on('uploadError', function (file, reason) {
77         $(up_status).addClass('f').removeClass('i s');
78         uploader.removeFile(file);
79         uploader.reset();
80     });
81     uploader.on("uploadFinished", function () {
82         uploader.destroy();
83         uploadfilefun(o);
84     });
85     uploader.on("error", function (type) {
86         if (type == "Q_TYPE_DENIED") {
87             showMessage('请上传Word,Excel,MP4,SWF,PDF,PPT,JPG,PNG格式文件!', "428px", "70px");
88         } else if (type == "F_EXCEED_SIZE") {
89             showMessage('文件大小不能超过500MB!', "328px", "70px");
90         } else {
91             showMessage("服务器出错!请检查后重新上传。", "362px", "70px");
92         }
93     });
94     return uploader;
95 }

分段上传配置注意事项:

1.Create()方法配置Chunked:true;表示以分段方式上传

2.Chunksize:1024*1024;分段的大小,建议不要过小或过大,网络允许的情况1M是可以的

3.formData:{guid:guid},自定义GUID编码

4.uploadSuccess()方法定义回调函数,实现分段文件合并

实例

文件分段上传后端编码:

 

        /// <summary>
        /// 分段上传课程资源
        /// </summary>
        /// <returns></returns>
        public ActionResult ChunkUploadFile()
        {
            int chunks = Convert.ToInt32(Request["chunks"]);
            int index = Convert.ToInt32(Request["chunk"]);//当前分块序号
            var guid = Request["guid"];//前端传来的GUID号
            var dir = string.Format("{0}Upload\\CourseResource\\{1}", WebConfigInfo.PhysicalApplicationPath,guid);
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            string filePath = Path.Combine(dir, index.ToString());
            HttpFileCollection file_upload = System.Web.HttpContext.Current.Request.Files;
            var name = Path.GetFileNameWithoutExtension(file_upload[0].FileName);
            var fileExtension = Path.GetExtension(file_upload[0].FileName);
            var fileName = Guid.NewGuid().ToString() + fileExtension;
            file_upload[0].SaveAs(filePath);
            return Json(new
            {
                Status = 1,
                Name = name,
                Suffix = fileExtension
            });
        }

上传成功后回调函数执行文件合并,代码如下:

        /// <summary>
        /// 合并分段文件
        /// </summary>
        /// <returns></returns>
        public ActionResult Merge()
        {
            var guid = Request["guid"];
            var uploadDir = string.Format("{0}Upload\\CourseResource",WebConfigInfo.PhysicalApplicationPath);
            var dir = Path.Combine(uploadDir, guid);//临时文件夹
            var fileExtension = Request["suffix"];
            var fileName = Guid.NewGuid().ToString() + fileExtension;
            try
            {
                var files = System.IO.Directory.GetFiles(dir);//获得guid下所有文件
                var finalPath = Path.Combine(uploadDir, fileName);//最终的文件名
                var fs = new FileStream(finalPath, FileMode.Create);
                foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排序合并
                {
                    var bytes = System.IO.File.ReadAllBytes(part);
                    fs.Write(bytes, 0, bytes.Length);
                    bytes = null;
                    System.IO.File.Delete(part);//删除分块
                }
                fs.Close();
                System.IO.Directory.Delete(dir);//删除文件夹
                var fileGuid = string.Format("/Upload/CourseResource/{0}", fileName);
                return Json(new { Status = 1, fileGuid = fileGuid });
            }
            catch (Exception ex)
            {
                return Json(new { Status = 0,Message=ex.Message });
            }
            
        }

 

posted @ 2017-11-06 15:14  念冬的叶子  阅读(509)  评论(0编辑  收藏  举报