zoukankan      html  css  js  c++  java
  • net core 断点上传

    一、前言

        关于这边文章,一直都想写上去来做记录,终于今晚是看了《我想我们在一起》这电影之后,触动而写。 有些事情还是不要等待,能当下做就赶紧做,不然都是给自己遗憾的。 回归正题,说的是断点上传,需要把文件切割成片。下面是我个人的大概思路,也借鉴了百度一些前辈们留下的经验而成(说借鉴其实差不多就是ctrl+c  和ctrl+v 的问题)。

    二、前端代码

        只是提供一个分片思路。 个人感觉下面js 代码标红部分是比较重要的吧。

     <input class="easyui-filebox" name="filevideo" id="filevideo" labelPosition="top" data-options="prompt:'请选择视频',buttonText:'选择',accept:'video/avi,audio/mp4, video/mp4,video/mpeg,video/avi'">
           

    var bytesPerPiece = 1024*1024 ; // 每个文件切片大小定为1MB . var totalPieces; //发送请求 window.uploads = function (obj) { var blob =$("#filevideo").filebox("files")[0];//1.获取文件对象 var start = 0; var end; var index = 0;//索引片数 var filesize = blob.size;//2.文件大小 var filename = blob.name;//3.文件名称带后缀名 if (filename.indexOf(".mp4") == -1) { $.messager.alert('提示', '目前只支持上传mp4格式'); return; }
    //计算文件切片总数 totalPieces = Math.ceil(filesize / bytesPerPiece); //4.计算分片总数 var guid= '@Guid.NewGuid().ToString()';//这是我自定义的,以GUID 命名一个临时文件夹
            //5.开始分片
    while (start < filesize) { end = start + bytesPerPiece; if (end > filesize) { end = filesize; } var chunk = blob.slice(start, end);//6.切割文件 var formData = new FormData();//7.用FormData 附带参数 上传文件 formData.append("file", chunk, filename); formData.append("fileName", fid); formData.append("totalPieces", totalPieces); formData.append("currentPieces", index + 1); formData.append("guid", guid); $.ajax({ url: '@Url.Content("~/Admins/Video/UploadFile")', type: 'POST', cache: false,//这个很重要 data: formData, processData: false,//这个很重要 contentType: false, dataType:'json', }).done(function (result) {             
                
                //这一句防止重复调用
    if (proceseBarVal == 100) { return; } if (result.isuccess)//是否上传成功 { if (servercurent.currentPieces != -1) { //这里是计算当前进度 } else { //完成上传 //执行合并接口 $.ajax({ url: '@Url.Content("~/Admins/Video/MeterFile")', type: 'POST', cache: false, data: data, dataType: "json", success: function (res) { if (res.success) { } else { $.messager.alert("提示", res.msg) } } }); } } }).fail(function (res) { }); start = end; index++; } }

    三、后端代码

         看这代码还是有点混乱的,没有做整理。 后续附加一个demo出来比较好。

    /// <summary>
            /// 文件上传
            /// </summary>
            /// <param name="fileName">临时文件夹名称</param>
            /// <param name="totalPieces"></param>
            /// <param name="currentPieces"></param>
            /// <returns></returns>
            [HttpPost]
            public async Task<string> UploadFile(string fileName, string totalPieces, string currentPieces,string guid)
            {
                ResultData rmodel = new ResultData();
                string ID = Guid.NewGuid().ToString();
                try
                {
                    var filebase = Request.Form.Files;
                    string webRootPath = _hostingEnvironment.WebRootPath;
                    string virRoot = "/files/video/temp/" + UserName+ "/" + DateTime.Now.ToString("yyyyMMdd") + "/" + guid + "/";//虚拟路径,用于存数据库
                    if (!Directory.Exists(webRootPath + virRoot))
                        Directory.CreateDirectory(webRootPath + virRoot);
                    if (filebase.Count > 0)
                    {
                        for (int i = 0; i < filebase.Count; i++)
                        {
                            var file = filebase[i];
    
                            virRoot = virRoot + currentPieces;
    
                            var filePath = webRootPath + virRoot;
    
                            using (var stream = new FileStream(filePath, FileMode.Create))
                            {
                                await file.CopyToAsync(stream).ConfigureAwait(false);
                            }
    
    
                            if (totalPieces == currentPieces)
                            {
                                string extName = FileHelper.GetFileExtendName(filebase[i].FileName);
                                //上传完毕之后,就直接合并! 
                                rmodel.data = new
                                {
                                    dir = webRootPath + "/files/video/temp/" + UserName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/" + guid + "/",
                                    exName = Guid.NewGuid().ToString() + extName,
                                    currentPieces = -1 //MeterFile(webRootPath + "/files/video/temp/" + UserName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/" + guid+ "/", Guid.NewGuid().ToString() + extName),
                                };
                                rmodel.isuccess = true;
                                rmodel.msg = "上传成功!";
                            }
                            else
                            {
                                rmodel.isuccess = true;
                                rmodel.data = new
                                {
                                    currentPieces = currentPieces
                                };
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    rmodel.msg = ex.Message;
                }
    
                return rmodel.ToJson();
            }
    
    
            /// <summary>
            /// 合并文件
            /// </summary>
            [HttpPost]
            public AjaxResult MeterFile(string dir, string exName)
            {
                AjaxResult result = new AjaxResult() {  Success=false};
                try
                {
                    var files = System.IO.Directory.GetFiles(dir);//获得下面的所有文件  
                    string localhost = dir.Replace("temp/" + UserName + "/", "");
                    if (!Directory.Exists(localhost))
                        Directory.CreateDirectory(localhost);
                    var fs = new FileStream(localhost + exName, 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.Close();
                    //System.IO.Directory.Delete(dir);//删除文件夹 
                    result.Msg = "上传成功";
                    result.Success = true;
                    result.Data = new
                    {
                        url = Path.Combine(dir.Replace(_hostingEnvironment.WebRootPath, "").Replace("temp/" + UserName + "/", ""), exName)
                    };
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog_LocalTxt(ex.Message);
                    result.Msg = "合并失败,请联系管理员!";
                }
                
                return result;
            }

    四、结束

       在此代码之前,我是直接把文件切片上传之后,马上合并,导致一个问题就是,文件没有上传完成马上执行合并方法,1.删除文件夹报错  2.合并的视频无法播放或者播放不全。 后来跟同事讨论了一下,把文件上传完成之后,再请求合并接口(注意,必须要设置同步,异步的话会出现文件未上传完成就进行合并了)。我上面只是提供一个上传文件思路,并不是最优的代码。所以进行优化。 

  • 相关阅读:
    PHP数组操作,数组排序,数组元素操作,数组元素定位
    提高PHP编程效率的53个要点
    javascript的一些简单的应用
    数字时钟
    一个限定变量范围的小技巧
    windows编程学习——1 关闭窗口不退出
    比木马NB多了
    模拟时钟
    恶搞程序——黑屏
    用白色画笔再画一遍,代替擦除
  • 原文地址:https://www.cnblogs.com/mylinx/p/15018194.html
Copyright © 2011-2022 走看看