BkCoding

A responsible theme for WordPress

asp.net mvc+webuploader大文件分片上传

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。

采用大文件分片并发上传,极大的提高了文件上传效率。

首先是前端:

var GUID = WebUploader.Base.guid();//一个GUID
    uploadereditsVideo = WebUploader.create({
        // swf文件路径
        swf: '../../Scripts/plugins/webuploader/Uploader.swf',
        // 文件接收服务端。
        server: '/AjaxUpload/ChunkUpload',
        pick: {
            id: '#picker',
            label: '上传',
            innerHTML: '上传',
            multiple: false
        },
        fileNumLimit: 1,
        fileSingleSizeLimit: 1024 * 1024 *100,
        chunked: true,//开始分片上传
        chunkSize: 1024 * 1024 * 2,//每一片的大小
        formData: {
            guid: GUID //自定义参数
        }
    });

    uploadereditsVideo.on('fileQueued', function (file) {
        uploadereditsVideo.upload();
    });
    // 文件上传成功
    uploadereditsVideo.on('uploadSuccess', function (file, response) {
        //合并文件
        $.post('/AjaxUpload/Merge', { guid: GUID, fileName: file.name }, function (data) {
            if (data.r == 1) {
                alert("上传完成");
            }
            else {
                alert(data.err);
            }
        });
    });

后端接收方法Upload

public ActionResult Upload()
        {
            //如果进行了分片
            if (Request.Form.AllKeys.Any(m => m == "chunk"))
            {
                //取得chunk和chunks
                int chunk = Convert.ToInt32(Request.Form["chunk"]);//当前分片在上传分片中的顺序(从0开始)
                int chunks = Convert.ToInt32(Request.Form["chunks"]);//总分片数
                //根据GUID创建用该GUID命名的临时文件夹
                string folder = Server.MapPath("~/upload/" + Request["guid"] + "/");
                string path = folder + chunk;

                //建立临时传输文件夹
                if (!Directory.Exists(Path.GetDirectoryName(folder)))
                {
                    Directory.CreateDirectory(folder);
                }

                FileStream addFile = new FileStream(path, FileMode.Append, FileAccess.Write);
                BinaryWriter AddWriter = new BinaryWriter(addFile);
                //获得上传的分片数据流
                var file = Request.Files[0];
                Stream stream = file.InputStream;

                BinaryReader TempReader = new BinaryReader(stream);
                //将上传的分片追加到临时文件末尾
                AddWriter.Write(TempReader.ReadBytes((int)stream.Length));
                //关闭BinaryReader文件阅读器
                TempReader.Close();
                stream.Close();
                AddWriter.Close();
                addFile.Close();

                TempReader.Dispose();
                stream.Dispose();
                AddWriter.Dispose();
                addFile.Dispose();
                return Json(new { chunked = true, hasError = false, f_ext = Path.GetExtension(file.FileName) });
            }
            else//没有分片直接保存
            {
                Request.Files[0].SaveAs(Server.MapPath("~/upload/" + DateTime.Now.ToFileTime() + Path.GetExtension(Request.Files[0].FileName)));
                return Json(new { chunked = true, hasError = false });
            }
        }

接下来是合并文件方法

public ActionResult Merge()
        {
            try
            {
                var guid = Request["guid"];//GUID
                var uploadDir = Server.MapPath("~/upload");//Upload 文件夹
                var dir = Path.Combine(uploadDir, guid);//临时文件夹
                var ext = Path.GetExtension(Request["fileName"]);
                var files = Directory.GetFiles(dir);//获得下面的所有文件
                var name = Guid.NewGuid().ToString("N") + ext;
                var finalPath = Path.Combine(uploadDir, name);//最终的文件名
                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();
                Directory.Delete(dir);//删除文件夹
                return Json(new { r = 1, path = "/upload/" + name });
            }
            catch (Exception ex)
            {
                return Json(new { r = 0, err = ex.Message });
            }
        }

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注