博客
关于我
强烈建议你试试无所不能的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

你可能感兴趣的文章
XHTML学习资料(五)—— 表单
查看>>
练习题解答(一)
查看>>
RabbitMQ 应用二
查看>>
zabbix监控tomcat与安全规范
查看>>
Ubuntu-10.10如何给用户添加sudo权限
查看>>
记录系统日志方法
查看>>
摘自当当网的36类商品分类菜单
查看>>
js判断客户端是pc还是手机
查看>>
cast——java类型转换
查看>>
linux 切换c++版本
查看>>
静态方法和实例方法联系与区别
查看>>
java 正则获取html的值
查看>>
NOI2015
查看>>
Eclipse导入别人项目爆红叉
查看>>
JVM(四、尝试编写类加载器)
查看>>
Extjs 4.2使用心得 --- store和reader使用技巧
查看>>
文本框 只能输入数字和小数点验证
查看>>
HIbernate学习笔记(八) hibernate缓存机制
查看>>
struts2从浅至深(三)拦截器
查看>>
Eclipse 项目run时 Console控制台输出中文乱码问题的解决方法
查看>>