博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用HTML5 FormData对象实现大文件分块上传(断点上传)功能
阅读量:6824 次
发布时间:2019-06-26

本文共 7255 字,大约阅读时间需要 24 分钟。

  FormData是HTML5新增的一个对象,通过FormData对象可以组装一组用 发送请求的键/值对。它可以更灵活方便的发送表单数据,因为可以独立于表单使用。如果你把表单的编码类型设置为multipart/form-data ,则通过FormData传输的数据格式和表单通过 方法传输的数据格式相同。具体用法参考 。

  实现逻辑:客户端首先请求接口,获取一个唯一的UploadID,然后每次按照固定大小读取文件块,同时计算需要上传的总块数total,将UploadID、total、当前上传文件块的下标index、文件名称以及文件块上传到服务端,服务端根据以上参数把文件块保存到临时目录,同时判断文件块是否已经全部上传完,如果已全部上传,则需要进行合并操作,最后会返回合并后的文件信息。我的例子中,把获取UploadID的步骤跟上传放在了一起,上传接口中会判断如果UploadID为空并且index为1,则会生成一个UploadID并返回,后续每次上传都需要带上UploadID参数。

  一下前端代码

  前端代码

1 @{ 2     Layout = null; 3 } 4  5  6  7  8  9     
10 断点上传11 12 13 14 15 16 17 18 19 98 99
前端代码

 

  服务端代码

1 using System;  2 using System.IO;  3 using System.Linq;  4 using System.Web;  5   6 namespace UploadTest  7 {  8     public class UploadHelper  9     { 10  11         private UploadHelper() 12         { 13  14         } 15  16         public UploadHelper(string fileRootPath) 17         { 18             if (string.IsNullOrWhiteSpace(fileRootPath)) 19                 throw new ArgumentNullException("fileRootPath", "fileRootPath is null"); 20  21             FileRootPath = fileRootPath; 22             BlockRootPath = fileRootPath + "/blocktmp/"; 23         } 24         ///  25         /// 块文件存储根路径 26         ///  27         private string BlockRootPath { get; set; } 28  29         ///  30         /// 文件存储根路径 31         ///  32         public string FileRootPath { get; set; } 33  34         ///  35         /// 分块上传 36         ///  37         public UploadResult Upload(string uploadId, int blockCount, int currIndex, string fileName, HttpPostedFileBase file) 38         { 39             try 40             { 41                 if (file == null) 42                     return new UploadResult { Msg = "请选择文件~" }; 43                 if (blockCount < 1) 44                     return new UploadResult { Msg = "块数量不能小于1~" }; 45                 if (currIndex < 0) 46                     return new UploadResult { Msg = "块数量小于0~" }; 47                 if (string.IsNullOrWhiteSpace(uploadId) && currIndex > 1) 48                     return new UploadResult { Msg = "上传编号为空~" }; 49  50                 var result = new UploadResult { Code = 1, Msg = "上传成功~" }; 51  52                 //首次上传需创建上传编号 53                 if (string.IsNullOrWhiteSpace(uploadId) || uploadId.Equals("undefind")) 54                     uploadId = GenerateUploadId(); 55  56                 result.UploadID = uploadId; 57  58                 #region ==块处理== 59  60                 //块文件名称 61                 var blockName = $"{uploadId}_{currIndex}.block"; 62                 //块文件目录路径 63                 var blockPath = Path.Combine(BlockRootPath, uploadId); 64                 //块文件目录对象 65                 DirectoryInfo blockDirectoryInfo = Directory.Exists(blockPath) ? new DirectoryInfo(blockPath) : Directory.CreateDirectory(blockPath); 66                 //块文件完整路径 67                 var blockFullPath = Path.Combine(blockPath, blockName); 68                 if (File.Exists(blockFullPath)) 69                 { 70                     //块已上传,不做失败处理 71                     return new UploadResult { Code = 1, Msg = "该文件块已上传~" }; 72                 } 73  74                 file.SaveAs(blockFullPath); 75  76                 #endregion 77  78                 #region ==块合并处理== 79  80                 //判断块文件是否已将上传完,上传完合并文件 81                 if (blockDirectoryInfo.GetFiles().Count().Equals(blockCount)) 82                 { 83                     var timestamp = DateTime.Now.ToString("yyyMMdd"); 84                     fileName = uploadId + "." + GetExtension(fileName); 85                     var filePath = Path.Combine(FileRootPath, timestamp); 86                     if (!Directory.Exists(filePath)) 87                     { 88                         Directory.CreateDirectory(filePath); 89                     } 90                     //完整文件存储路径 91                     var fileFullPath = Path.Combine(filePath, fileName); 92                     using (var fs = new FileStream(fileFullPath, FileMode.Create)) 93                     { 94                         for (var i = 1; i <= blockCount; i++) 95                         { 96                             var path = Path.Combine(blockPath, $"{uploadId}_{i}.block"); 97                             var bytes = File.ReadAllBytes(path); 98                             fs.Write(bytes, 0, bytes.Length); 99                         }100                         Directory.Delete(blockPath, true);101 102                         result.FileInfo = new UploadFileInfo103                         {104                             FileName = fileName,105                             FilePath = Path.Combine(timestamp, fileName)106                         };107                     }108                 }109 110                 return result;111                 #endregion112             }113             catch (Exception ex)114             {115                 return new UploadResult { Msg = ex.Message };116             }117         }118 119         /// 120         /// 生成上传唯一编号121         /// 122         /// 
123 public string GenerateUploadId()124 {125 var guid = Guid.NewGuid().ToString();126 return guid.Replace("-", "");127 }128 129 /// 130 /// 获取文件扩展名131 /// 132 /// 133 ///
134 public string GetExtension(string fileName)135 {136 if (string.IsNullOrWhiteSpace(fileName) || fileName.IndexOf(".") < 0)137 {138 return string.Empty;139 }140 var arr = fileName.Split('.');141 return arr[arr.Length - 1];142 }143 }144 /// 145 /// 文件上传结果146 /// 147 public class UploadResult148 {149 /// 150 /// 状态码 0失败 1成功151 /// 152 public int Code { get; set; }153 /// 154 /// 消息155 /// 156 public string Msg { get; set; }157 /// 158 /// 上传编号,唯一159 /// 160 public string UploadID { get; set; }161 /// 162 /// 文件保存信息163 /// 164 public UploadFileInfo FileInfo { get; set; }165 166 }167 public class UploadFileInfo168 {169 /// 170 /// 文件保存名称171 /// 172 public string FileName { get; set; }173 /// 174 /// 文件保存路径175 /// 176 public string FilePath { get; set; }177 /// 178 /// 文件MD5值179 /// 180 public string MD5 { get; set; }181 }182 }
UploadHelper

 

  Controller代码

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace UploadTest.Controllers{    [RoutePrefix("upload")]    public class UploadController : Controller    {        [Route]        [HttpGet]        public ActionResult Index()        {            return View();        }        [Route]        [HttpPost]        public ActionResult Upload(string uploadId,int total,int index,string fileName)        {            var helper = new UploadHelper("D:\\Upload");            var result = helper.Upload(uploadId, total, index, fileName, Request.Files[0]);            return Json(result);        }    }}

 

转载于:https://www.cnblogs.com/oldli/p/7271675.html

你可能感兴趣的文章
AndroidStudio用Cmake方式编译NDK代码(cmake配置.a库)
查看>>
OSChina 周四乱弹 ——黑丝短裙java程序员同事
查看>>
设置iptables之后不能正常访问ftp解决方法
查看>>
移动端rem布局
查看>>
jsp与iframe跨域访问的一个方法
查看>>
ViewPager + Fragment 取消预加载
查看>>
BigDecimal 02 - 注意事项
查看>>
用js玩桌球游戏
查看>>
maven下运行jetty报错
查看>>
android 配置framework 使应用首选安装在SD卡
查看>>
h5 点击表单 顶部fixed 菜单栏 上移
查看>>
windows 2008 R2 64位系统杀毒软件
查看>>
我的友情链接
查看>>
netty学习笔记
查看>>
更改win7文件类型默认操作
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Webgoat 笔记总结 Web Services
查看>>
Linux Mysql安装部署
查看>>
多线程 概述
查看>>