多文件上传,大文件上传3、5个G,那都不是事

一套大文件上传的教程给大家。

https://www.yyjcw.com/html/ke/34.html

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

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

扫描二维码关注公众号,回复: 10891833 查看本文章

直接上代码:

前台前端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

源码和技术咨询微信号:yyjcw10000  QQ:1416759661

发布了8 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

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