asp.net大文件分块上传视频教程

楼主博文写得好,我也来推荐一套大文件上传的教程给大家。
http://yyjcw.com/html/News/1941.html

重点讲解了多文件上传,大文件上传,分块上传,断点续传,文件秒传,上传失败自动修复再上传等功能,只要你按照课程中讲解的做,上传3、5个G,那都不是事。特别是大文件秒传功能,不仅节省了上传时间,还节省了网络带宽和服务器空间。


我们平时做业务系统的时候,一般都会使用表单提交数据,提交数据的时候常常又伴随着附件的上传,如果附件小,用传统的办法就能解决,如果附件比较大,比如板给你安排一个上传视频的任务,视频文件一般都比较大,动不动就是几个G,用传统的办法就显得非常有限。为了帮助大家解决大文件上传的问题,我们特别录制了本套视频教程,本套视频教程高度压缩的精华版,没有废话,重点讲解了多文件上传,大文件上传,分块上传,断点续传,文件秒传,上传失败自动修复再上传等功能,只要你按照课程中讲解的做,上传3、5个G,那都不是事。特别是大文件秒传功能,不仅节省了上传时间,还节省了网络带宽和服务器空间,采用md5加密标识文件唯一性,避免了同一文件的重复上传,上传过程带进度条,即时显示上载数据量和上载百分比。求人不如求己,搞定这些技术,让老板加薪,再也不用低三下四的求人,大文件上传无压力,让学习更高效,让工作更轻松,妈妈再也不用担心你的学习!





直接上代码:

 

前台前端index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
<! DOCTYPE  html>
< html >
 
     < head >
         < meta  charset="utf-8" />
         < title >夜鹰教程网大文件分块上传</ title >
         < style  type="text/css">
             * {
                 font-family: "微软雅黑";
                 margin: 0;
                 padding: 0;
             }
             
             .container {
                 padding-top: 10px;
                 padding-left: 10px;
             }
             
             .container input {
                 width: 120px;
                 height: 30px;
                 background-color: blue;
                 color: white;
                 border: 0;
                 line-height: 30px;
                 border-radius: 5px;
                 margin-right: 5px;
                 outline: none;
                 cursor: pointer;
             }
             
             #filelist {
                 width: 800px;
                 border: solid 1px #eee;
                 border-collapse: collapse;
                 margin: 10px;
             }
             
             #filelist td {
                 border-bottom: solid 1px #eee;
                 height: 30px;
                 font-size: 12px;
                 /*line-height:30px ;*/
                 padding: 0 3px;
             }
             
             .filename {
                 width: 200px;
                 text-align: center;
             }
             
             .filestatus {
                 width: 100px;
                 text-align: center;
             }
             
             .fileprogress {
                 text-align: center;
             }
             
             .domprogress {
                 width: 320px;
             }
             
             .domsize {
                 display: block;
             }
             
             #tdmsg {
                 text-align: center;
             }
             
             #fileselect {
                 display: none;
             }
 
             span.domtime {
                 display:block;
             }
         </ style >
 
     </ head >
 
     < body >
         < div  class="container">
             < input  type="file" name="fileselect" id="fileselect" value="" multiple/>
             < input  type="button" id="btnselect" value="选择上传的文件" />
             < input  type="button" id="btnupload" value="开始上传" />
         </ div >
 
         < table  cellspacing="0" cellpadding="0" id="filelist">
             < tr >
                 < td  class="filename">文件名</ td >
                 < td  class="fileprogress">进度</ td >
                 < td  class="filestatus">状态</ td >
             </ tr >
             <!--<tr><td>人民的名义.avi </td><td><progress value="10" max="100" class="domprogress"></progress><span class="dompercent">10%</span><span class="domsize">0/1.86GB</span></td><td class="filestatus"><span class="domstatus">排队中</span></td></tr>-->
             < tr  id="trmsg">
                 < td  colspan="3" id="tdmsg">请选择要上传的文件! 技术支持QQ:1416759661</ td >
             </ tr >
 
         </ table >
         < script  src="js/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></ script >
         < script  src="js/spark-md5.js" type="text/javascript" charset="utf-8"></ script >
         < script  type="text/javascript">
             $("#btnselect").click(function() {
                 $("#fileselect").click();
             });
 
             $("#fileselect").change(function() {
                 var files = this.files;
                 if(files.length > 0) {
                     $("#trmsg").remove();
                     $(files).each(function(index, item) {
                         console.log(index, item);
                         var filesize = 0;
                         if((item.size / 1024 / 1024 / 1024) >= 1) {
                             filesize = (item.size / 1024 / 1024 / 1024).toFixed(2) + "GB"; // b=>kb=>mb=>gb
                         } else if((item.size / 1024 / 1024 / 1024) <  1  && (item.size / 1024 / 1024) >= 1) {
                             filesize = (item.size / 1024 / 1024).toFixed(2) + "MB";
                         } else if((item.size / 1024 / 1024) <  1  && (item.size / 1024) >= 1) {
                             filesize = (item.size / 1024).toFixed(2) + "KB";
                         } else {
                             filesize = item.size + "B";
                         }
 
                         var htmlstr = '< tr >< td >' + item.name + '</ td >< td >< progress  value="0" max="100" class="domprogress"></ progress >< span  class="dompercent"> 0/'+filesize+'</ span >< span  class="domtime">总共耗时:0 秒</ span ></ td >< td  class="filestatus">< span  class="domstatus">排队中</ span ></ td ></ tr >';
                         $("#filelist").append(htmlstr);
 
                     });
 
                 }
 
             });
 
             $("#btnupload").click(function() {
 
                 var files = $("#fileselect")[0].files;
                 $(files).each(function (index, item) {
                     yyupload(files[index], $("span.domstatus").eq(index), $("span.dompercent").eq(index), $(".domprogress").eq(index), $("span.domtime").eq(index));
                 });               
             });
 
             //文件上传
             function yyupload(file, dommsg, dompercentmb, domprogress, domtime, fn) {
                 var startTime = new Date();
                 //获取文件的md5字符串,用于标识文件的唯一性。
                 calculate(file);
                 //获取文件的加密字符串
                 function calculate(file) {
                     var fileReader = new FileReader();
                     var chunkSize = 1024 * 1024 * 5; //每次读取5MB
                     var chunksCount = Math.ceil(file.size / chunkSize); //回大于参数x的最小整数 8=》8  8.4=》9  8.5=》9 -8.5=》-8
                     var currentChunk = 0; //当前块的索引
                     var spark = new SparkMD5();
                     fileReader.onload = function(e) {
                         console.log((currentChunk + 1) + "/" + chunksCount)
                         dommsg.text("正在检查文件: " + (currentChunk + 1) + "/" + chunksCount);
                         spark.appendBinary(e.target.result); // 添加二进制字符串
                         currentChunk++;
                         if(currentChunk <  chunksCount ) {
                             loadNext();
                         } else {
                             var md5value = spark.end();
                             console.log("文件加密结束,密钥为:" + md5value);
                             checkfile(md5value, file); //检查服务器是否存在该文件,存在就从断点继续上传
                         }
                     };
 
                     function loadNext() {
                         var start = currentChunk * chunkSize; //计算读取开始位置
                         var end = start + chunkSize >= file.size ? file.size : start + chunkSize; //计算读取结束位置
                         fileReader.readAsBinaryString(file.slice(start, end)); //读取为二进制字符串
                     };
                     loadNext();
                 }
 
                 var repeatcount = 0;
                 //检查文件是否已经存在
                 function checkfile(md5value, file) {
                     var fd = new FormData();
                     fd.append('rquesttype', "chekcfile");
                     fd.append('filename', file.name);
                     fd.append('md5value', md5value);
                     var xhr = new XMLHttpRequest();
                     xhr.open('post', 'FileUpoload.ashx', true);
                     xhr.onreadystatechange = function(res) {
                         if(xhr.readyState == 4 && xhr.status == 200) {
                             var jsonobj = JSON.parse(xhr.responseText); //可以将json字符串转换成json对象  //JSON.stringify(jsonobj); //可以将json对象转换成json对符串
                             console.log("继续上传的位置:" + jsonobj.startindex);
                             switch(jsonobj.flag) {
                                 case "0":
                                     doUpload(md5value, file, 0);
                                     break;
                                 case "1":
                                     doUpload(md5value, file, parseInt(jsonobj.startindex));
                                     break;
                                 case "2":
                                     secondUpload(file);
                                     break;
                             }
                             repeatcount = 0;
                         } else if(xhr.status == 500) {
                             setTimeout(function() {
                                 if(repeatcount <  3 ) {
                                     checkfile(md5value, file);
                                 }
                                 repeatcount++;
                             }, 3000);
                         }
                     }
                     //开始发送
                     xhr.send(fd);
                 }
 
                 //实现秒传功能
                 function secondUpload(file)
                 {
                     var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
                     domtime.text("耗时" + timerange + "秒");
                     //显示结果进度
                     var percent =100;
                     dommsg.text(percent.toFixed(2) + "%");
                     domprogress.val(percent);
                     var total = file.size;
                     if (total > 1024 * 1024 * 1024) {
                         dompercentmb.text((total / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
                     } else if (total > 1024 * 1024) {
                         dompercentmb.text((total / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
                     } else if (total > 1024 && total <  1024  * 1024) {
                         dompercentmb.text((total / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
                     } else {
                         dompercentmb.text((total).toFixed(2) + "B/" + (total).toFixed(2) + "B");
                     }
 
                 }
 
 
 
                 //上传文件
                 function doUpload(md5value,file,startindex) {
                     var reader = new FileReader();//新建一个读文件的对象
                     var step = 1024 * 200; //每次读取文件大小  200KB
                     var cuLoaded = startindex; //当前已经读取总数
                     var total = file.size;//文件的总大小
                     //读取一段成功
                     reader.onload = function (e) {
                         //处理读取的结果
                         var result = reader.result; //本次读取的数据
                         var loaded = e.loaded; //本次读取的数据长度
                         uploadFile(result, cuLoaded, function () { //将分段数据上传到服务器
                             cuLoaded += loaded; //如果没有读完,继续
                             var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
                             if (total > 1024 * 1024 * 1024) {
                                 dompercentmb.text((cuLoaded / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
                             } else if (total > 1024 * 1024) {
                                 dompercentmb.text((cuLoaded / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
                             } else if (total > 1024 && total <  1024  * 1024) {
                                 dompercentmb.text((cuLoaded / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
                             } else {
                                 dompercentmb.text((cuLoaded).toFixed(2) + "B/" + (total).toFixed(2) + "B");
                             }
 
                             domtime.text("耗时" + timerange + "秒");
                             if (cuLoaded < total) {
                                 readBlob(cuLoaded);
                             } else {
                                 console.log('总共用时:' + timerange);
                                 cuLoaded = total;
                                 sendfinish(); //告知服务器上传完毕  
                                 domtime.text("上传完成,总共耗时" + timerange + "秒");
                             }
                             //显示结果进度
                             var percent = (cuLoaded/total) * 100;
                             dommsg.text(percent.toFixed(2) + "%");
                             domprogress.val(percent);
                         });
                     }
                     var k = 0;
                     function sendfinish() {
                         var fd = new FormData();
                         fd.append('rquesttype', "finishupload");
                         fd.append('filename', file.name);
                         fd.append('md5value', md5value);
                         fd.append('totalsize', file.size);
                         var xhr = new XMLHttpRequest();
                         xhr.open('post', 'FileUpoload.ashx', true);
                         xhr.onreadystatechange = function () {
                             if (xhr.readyState == 4 && xhr.status == 200) {
                                 if (fn) {
                                     fn(); //如果上传成功,继续上传下一个文件
                                 }
                                 k = 0;
                             } else if (xhr.status == 500) {
                                 setTimeout(function () {
                                     if (k < 3) {
                                         sendfinish();
                                         //上传完毕的前端处理
                                     }
                                     k++
                                 }, 3000);
                             }
                         }
                         //开始发送
                         xhr.send(fd);
                     }
                     var m = 0;
                     //关键代码上传到服务器
                     function uploadFile(result, startIndex, onSuccess) {
                         var blob = new Blob([result]);
                         //提交到服务器
                         var fd = new FormData();
                         fd.append('file', blob);
                         fd.append('rquesttype',"uploadblob");                      
                         fd.append('filename', file.name);
                         fd.append('md5value', md5value);
                         fd.append('loaded', startIndex);
                         var xhr = new XMLHttpRequest();
                         xhr.open('post', 'FileUpoload.ashx', true);
                         xhr.onreadystatechange = function () {
                             if (xhr.readyState == 4 && xhr.status == 200) {
                                 m = 0;
                                 if (onSuccess)
                                     onSuccess();
                             } else if (xhr.status == 500) {
                                 setTimeout(function () {
                                     if (m < 3) {
                                         containue();
                                         m++;
                                     }
                                 }, 1000);
                             }
                         }
                         //开始发送
                         xhr.send(fd);
                     }
 
                     //指定开始位置,分块读取文件
                     function readBlob(start) {
                         //指定开始位置和结束位置读取文件
                         var blob = file.slice(start, start + step); //读取开始位置和结束位置的文件
                         reader.readAsArrayBuffer(blob); //读取切割好的文件块
                     }
                     //继续
                     function containue() {
                         readBlob(cuLoaded);
                     }
                     readBlob(cuLoaded);
                 }
 
                 
             }
         </script>
     </ body >
 
</ html >

需要到网上下载一个spark-md5.js文件,下载地址:

https://raw.githubusercontent.com/satazor/SparkMD5/master/spark-md5.js

后端处理请求的文件FileUpoload.ashx代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<%@ WebHandler Language= "C#"  Class= "FileUpoload"  %>
 
using  System;
using  System.Web;
using  System.IO;
using  Microsoft.VisualBasic.Devices;
 
public  class  FileUpoload : IHttpHandler {
     private  string  basefilename = HttpContext.Current.Server.MapPath( "/FileTemp/" );
     private  long  totalCount = 0;
     public  void  ProcessRequest (HttpContext context) {
         HttpRequest req=context.Request;
         string  rquesttype=req.Form[ "rquesttype" ];
         switch  (rquesttype)
         {
             case  "chekcfile" : chekcfile(req);  break ;
             case  "uploadblob" : uploadblob(req);  break ;
             case  "finishupload" : finishupload(req);  break ;
         }
         
     }
 
     /// <summary>
     /// 结束文件上传,修改上传后的名称
     /// </summary>
     /// <param name="req"></param>
     public  void  finishupload(HttpRequest req)
     {
         //接收前端传递过来的参数
         var  md5value = req.Form[ "md5value" ]; //文件md5加密的字符串
         var  filename = req.Form[ "filename" ]; //文件的名称
         var  totalsize = req.Form[ "totalsize" ]; //文件的总大小
         
         string  fullname = basefilename + md5value +  ".part" ; //上传的时候的名称
         string  okname = basefilename + md5value +  ".ok" ; //上传完毕之后再该目录下创建一个.ok后缀的文件,这个文件的大小为0,没有内容,不占空间,主要用于前端检查这个文件是否已经存在了
         var  oldname = basefilename + filename;
         Computer MyComputer =  new  Computer();
         try
         {
             File.Create(okname);         
             FileInfo fi =  new  FileInfo(oldname);
             if  (fi.Exists)
             {
                 fi.Delete();
             }
             MyComputer.FileSystem.RenameFile(fullname, filename);
         }
         catch  (Exception ex)
         {
 
         }
         finally
         {
             var  str =  string .Format( "{{\"data\":\"ok\"}}" );
             HttpContext.Current.Response.Write(str);
         }        
     }
 
     
     /// <summary>
     /// 处理文件分块上传的数据
     /// </summary>
     /// <param name="req"></param>
     public  void  uploadblob(HttpRequest req)
     {
         if  (req.Files.Count <= 0)
         {
             HttpContext.Current.Response.Write( "获取服务器上传文件失败" );
             return ;
         }
         HttpPostedFile _file = req.Files[0];
         //获取参数
         string  filename = req.Form[ "filename" ];
         string  md5value = req.Form[ "md5value" ];
         var  tempfilename = md5value +  ".part" ;
         //如果是int 类型当文件大的时候会出问题 最大也就是 1.9999999990686774G
         long  loaded = Convert.ToInt64(req.Form[ "loaded" ]);
         totalCount += loaded;
         string  newname = basefilename + tempfilename;
         Stream stream = _file.InputStream;
         if  (stream.Length <= 0)
             throw  new  Exception( "接收的数据不能为空" );
         byte [] dataOne =  new  byte [stream.Length];
         stream.Read(dataOne, 0, dataOne.Length);
         FileStream fs;
         try
         {
             fs =  new  FileStream(newname, FileMode.Append, FileAccess.Write, FileShare.Read, 1024);
             fs.Write(dataOne, 0, dataOne.Length);
             fs.Close();
         }
         catch  (Exception ex)
         {
 
         }
         finally
         {
             stream.Close();
             //检查文件已经上传的大小是否等于文件的总大小
         }
         HttpContext.Current.Response.Write( "分段数据保存成功" );
     }
 
     /// <summary>
     /// 检查文件是否存在
     /// </summary>
     /// <param name="req"></param>
     public  void  chekcfile(HttpRequest req)
     {
         var  md5value = req.Form[ "md5value" ]; //得到前端传递过来的文件的mdf字符串
         var  path_ok = basefilename + md5value +  ".ok" ;
         var  path_part = basefilename + md5value +  ".part" ;
         int  flag = 0;
         string  json =  string .Empty;
         if  (File.Exists(path_ok)) //传完了
         {
             flag = 2;
             json =  string .Format( "{{\"flag\":\"{0}\"}}" , flag);
         }
         else  if  (File.Exists(path_part)) //传了一部分
         {
             flag = 1;
             var  startindex =  new  FileInfo(path_part).Length.ToString();
             json =  string .Format( "{{\"flag\":\"{0}\",\"startindex\":\"{1}\"}}" , flag, startindex);
         }
         else //新文件
         {
             flag = 0;
             json =  string .Format( "{{\"flag\":\"{0}\",\"startindex\":\"0\"}}" , flag);
         }
         HttpContext.Current.Response.Write(json);
     }
  
     public  bool  IsReusable {
         get  {
             return  false ;
         }
     }
 
}如果看不懂以上代码,我们还有配套的视频教程,如果需要视频教程可以咨询QQ:1416759661
旺旺:   QQ:

猜你喜欢

转载自blog.csdn.net/tangyan1207/article/details/74937645