当前位置: 移动技术网 > IT编程>开发语言>.net > .NetCore+WebUploader实现大文件分片上传

.NetCore+WebUploader实现大文件分片上传

2019年10月23日  | 移动技术网IT编程  | 我要评论

国标07fj02,怎么追天蝎座男生,杉崎晴香

项目要求通过网站上传大文件,比如视频文件,通过摸索实现了文件分片来上传,然后后台进行合并。

使用了开源的前台上传插件webuploader(http://fex.baidu.com/webuploader/)

webuploader是由baidu webfe(fex)团队开发的一个简单的以html5为主,flash为辅的现代文件上传组件。在现代的浏览器里面能充分发挥html5的优势,同时又不摒弃主流ie浏览器,沿用原来的flash运行时,兼容ie6+,ios 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。

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

 

直接上代码,前台cshtml

@{
    layout = null;
}
<!doctype html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <link href="~/js/webuploader/webuploader.css" rel="stylesheet" />
    <link href="~/js/bootstrap.min.css" rel="stylesheet" />
    <script src="~/js/jquery.min.js"></script>
    <script src="~/js/webuploader/webuploader.js"></script>
    <title>upload</title>
    <script>
        jquery(function () {
            var $ = jquery,
                $list = $('#thelist'),
                $btn = $('#ctlbtn'),
                state = 'pending',
                filemd5,
                flag = true,
                datastate,
                fm = [],
                fnum,
                token,
                uploader;
            var fileext = ["mpg", "mpeg", "mp4", "avi"];
            token = '@viewbag.token';
            if (token == '' || token== 'undefined')
            {
                $("#uploader").hide();
                alert("登录超时,请重新登录。");
            }
            //监听分块上传过程中的三个时间点
            webuploader.uploader.register({
                "before-send-file": "beforesendfile",
                "before-send": "beforesend",
                "after-send-file": "aftersendfile",
            }, {
                    beforesendfile: function (file) {
                        var starttime = new date(file.lastmodifieddate);
                        filename = file.name;
                        var deferred = webuploader.deferred(); 
                        (new webuploader.uploader()).md5file(file, 0, 10 * 1024 * 1024)
                            .progress(function (percentage) {
                                console.log("正在读取文件");
                            })
                            .then(function (val) {
                                filemd5 = val;
                                fm.push(filemd5); 
                                deferred.resolve();
                            });
                        return deferred.promise();
                    },
                    //时间点2:如果有分块上传,则每个分块上传之前调用此函数
                    beforesend: function (block) {
                        var deferred = webuploader.deferred();
 
                        //上传前ajax检测一下此文件块是否已经上传
 
                        this.owner.options.formdata.filemd5 = filemd5;
                        this.owner.options.formdata.chunk = block.chunk;
                        deferred.resolve();
                        return deferred.promise();
                    },
                    //时间点3:所有分块上传成功后调用此函数
                    aftersendfile: function (file) {
                        var deferred = $.deferred();
                        $('#' + file.id).find('p.state').text('执行最后一步');
                        console.log(file);
                        console.log(file.guid);
                        $.ajax({
                            type: "post",
                            url: "/api/v1/check/filemerge",
                            data: {
                                guid: file.guid,
                                filemd5: fm[fnum],
                                filename: file.name
                            },
                            cache: false,
                            async: false,
                            success: function (response) {
                                fnum++;
                                console.log(response);
                                if (response.success == true) {
                                    datastate = response;
                                    flag = true;
                                } else {
                                    flag = false;
                                }
                                deferred.resolve();
                            },
                            error: function () {
                                fnum++;
                                datastate = undefined;
                                flag = false;
                                deferred.reject();
                            }
                        });
 
                        return deferred.promise();
                    }
                });
            uploader = webuploader.create({
                resize: false,
                filenumlimit: 10,
                swf: '/js/uploader.swf',
                server: '/api/v1/check/filesave',
                pick: '#picker',
                chunked: true,
                chunksize: 10 * 1024 * 1024,
                chunkretry: 5
                //, formdata: {
                //    guid: guid
                //}
            });
            uploader.on('beforefilequeued', function (file) {
                var isadd = false;
                for (var i = 0; i < fileext.length; i++) {
                    if (file.ext == fileext[i]) {
                        file.guid = webuploader.base.guid();
                        isadd = true;
                        break;
                    }
                }
                return isadd;
            });
            uploader.on('uploadbeforesend', function (object, data, headers) {
                //console.log(object);
                headers.authorization =token;
                data.guid = object.file.guid;
            });
            // 当有文件添加进来的时候
            uploader.on('filequeued', function (file) {
                $list.append('<div id="' + file.id + '" class="item">' +
                    '<h4 class="info">' + file.name + '</h4>' +
                    '<input type="hidden" id="h_' + file.id + '" value="' + file.guid + '" />' +
                    '<p class="state">等待上传...</p>' +
                    '</div>');
            });
 
            // 文件上传过程中创建进度条实时显示。
            uploader.on('uploadprogress', function (file, percentage) {
                var $li = $('#' + file.id),
                    $percent = $li.find('.progress .progress-bar');
                // 避免重复创建
                if (!$percent.length) {
                    $percent = $('<div class="progress progress-striped active">' +
                        '<div class="progress-bar" role="progressbar" style="width: 0%">' +
                        '</div>' +
                        '</div>').appendto($li).find('.progress-bar');
                }
                $li.find('p.state').text('上传中');
 
                $percent.css('width', percentage * 100 + '%');
            });
 
            uploader.on('uploadsuccess', function (file) {
                if (datastate == undefined) {
                    $('#' + file.id).find('p.state').text('上传失败');
                    $('#' + file.id).find('button').remove();
                    $('#' + file.id).find('p.state').before('<button id="retry" type="button" class="btn btn-primary fright retry pbtn">重新上传</button>');
                    flag = false;
                    file.setstatus('error');
                }
                if (datastate.success == true) {
                    $('#' + file.id).find('p.state').text('已上传');
                    $('#' + file.id).find('button').remove();
 
                } else {
                    $('#' + file.id).find('p.state').text('上传失败');
                    flag = false;
                }
            });
 
            uploader.on('uploaderror', function (file) {
                $('#' + file.id).find('p.state').text('上传出错');
            });
 
            uploader.on('uploadcomplete', function (file) {
                $('#' + file.id).find('.progress').fadeout();
            });
 
            uploader.on('all', function (type) {
                if (type === 'startupload') {
                    state = 'uploading';
                } else if (type === 'stopupload') {
                    state = 'paused';
                } else if (type === 'uploadfinished') {
                    state = 'done';
                }
                if (state === 'done') {
                    $btn.text('继续上传');
                } else if (state === 'uploading') {
                    $btn.text('暂停上传');
                } else {
                    $btn.text('开始上传');
                }
            });
            $btn.on('click', function () {
                if (state === 'uploading') {
                    uploader.stop();
                } else if (state == 'done') {
                    window.location.reload();
                }
                else {
                    uploader.upload();
                }
            });
        });
    </script>
</head>
<body>
    <div id="uploader" class="wu-example">
        <span style="color:red">只能上传mpg、mpeg、mp4、avi格式的视频文件</span>
        <div id="thelist" class="uploader-list"></div>
        <div class="btns">
            <div id="picker" class="webuploader-container"><div class="webuploader-pick">选择文件</div><div style="position: absolute; top: 0px; left: 0px; width: 88px; height: 34px; overflow: hidden; bottom: auto; right: auto;"><input type="file" name="file" class="webuploader-element-invisible" multiple="multiple"><label style="opacity: 0; width: 100%; height: 100%; display: block; cursor: pointer; background: rgb(255, 255, 255);"></label></div></div>
            <button id="ctlbtn" class="btn btn-default">开始上传</button> 
        </div>
    </div>
</body>
</html>

后台代码:

#region 上传视频
        public iactionresult upload()
        {
            viewbag.token = httpcontext.request.headers["authorization"];//获取认证信息,传递给前台,方便ajax请求时提供
            return view();
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        [httppost]
        public async task<iactionresult> filesave()
        {
            var date = request;
            var files = request.form.files;
            long size = files.sum(f => f.length);
            foreach (var formfile in files)
            {
                if (formfile.length > 0)
                {
                    string fileext = formfile.filename.substring(formfile.filename.indexof('.')); //文件扩展名,不含“.”
                    long filesize = formfile.length; //获得文件大小,以字节为单位
                    //string newfilename = guid.newguid().tostring() + "." + fileext; //随机生成新的文件名
                    string dirpath = path.combine(_uploadconfig.tmppath, request.form["guid"]);
                    if (!directory.exists(dirpath))
                    {
                        directory.createdirectory(dirpath);
                    }
                    var filepath = dirpath + "/" + request.form["chunk"] + fileext;
                    using (var stream = new filestream(filepath, filemode.create))
                    {
                        await formfile.copytoasync(stream);
 
                    }
                }
            }
            return ok(new { count = files.count, size });
        }
 
        /// <summary>
        /// 合并请求
        /// </summary>
        /// <returns></returns>
        [httppost]
        public async task<iactionresult> filemerge()
        {
            bool ok = false;
            string errmsg = "";
            try
            {
                var temporary = path.combine(_uploadconfig.tmppath, request.form["guid"]);//临时文件夹
                string filename = request.form["filename"];//文件名
                string fileext = path.getextension(filename);//获取文件后缀
                var files = directory.getfiles(temporary);//获得下面的所有文件
              
                var finalfilepath = path.combine(_uploadconfig.uploadpath + filename);//最终的文件名
                //var fs = new filestream(finalfilepath, filemode.create);
                using (var fs = new filestream(finalfilepath, filemode.create))
                {
                    foreach (var part in files.orderby(x => x.length).thenby(x => x))
                    {
                        var bytes = system.io.file.readallbytes(part);
                        await fs.writeasync(bytes, 0, bytes.length);
                        bytes = null;
                        system.io.file.delete(part);//删除分块
                    }
                    directory.delete(temporary);//删除文件夹
                    ok = true;
                }
            }
            catch (exception ex)
            {
                ok = false;
                errmsg = ex.message;
                log4net.error(errmsg);
            }
            if (ok)
            {
                return ok(new { success = true, msg = "" });
            }
            else
            {
                return ok(new { success = false, msg = errmsg }); ;
            }
        }
 
        #endregion

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网