温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

HTML5中文件域+FileReader如何分段读取文件并上传到服务器

发布时间:2021-07-24 11:58:59 来源:亿速云 阅读:173 作者:小新 栏目:web开发

这篇文章将为大家详细讲解有关HTML5中文件域+FileReader如何分段读取文件并上传到服务器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

说明:使用Ajax方式上传,文件不能过大,最好小于三四百兆,因为过多的连续Ajax请求会使后台崩溃,获取InputStream中数据会为空,尤其在Google浏览器测试过程中。

1.简单分段读取文件为Blob,ajax上传到服务器

<div class="container">     <div class="panel panel-default">         <div class="panel-heading">分段读取文件:</div>         <div class="panel-body">             <input type="file" id="file" />             <blockquote style="word-break:break-all;"></blockquote>         </div>     </div> </div>

JS:

/* * 分段读取文件为blob ,并使用ajax上传到服务器 * 分段上传exe文件会抛出异常 */ var fileBox = document.getElementById('file'); file.onchange = function () {     //获取文件对象     var file = this.files[0];     var reader = new FileReader();     var step = 1024 * 1024;     var total = file.size;     var cuLoaded = 0;     console.info("文件大小:" + file.size);     var startTime = new Date();     //读取一段成功     reader.onload = function (e) {         //处理读取的结果         var loaded = e.loaded;         //将分段数据上传到服务器         uploadFile(reader.result, cuLoaded, function () {             console.info('loaded:' + cuLoaded + 'current:' + loaded);             //如果没有读完,继续             cuLoaded += loaded;             if (cuLoaded < total) {                 readBlob(cuLoaded);             } else {                 console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);                 cuLoaded = total;             }         });     }     //指定开始位置,分块读取文件     function readBlob(start) {         //指定开始位置和结束位置读取文件         //console.info('start:' + start);         var blob = file.slice(start, start + step);         reader.readAsArrayBuffer(blob);     }     //开始读取     readBlob(0);     //关键代码上传到服务器     function uploadFile(result, startIndex, onSuccess) {         var blob = new Blob([result]);         //提交到服务器         var fd = new FormData();         fd.append('file', blob);         fd.append('filename', file.name);         fd.append('loaded', startIndex);         var xhr = new XMLHttpRequest();         xhr.open('post', '../ashx/upload2.ashx', true);         xhr.onreadystatechange = function () {             if (xhr.readyState == 4 && xhr.status == 200) {                 // var data = eval('(' + xhr.responseText + ')');                 console.info(xhr.responseText);                 if (onSuccess)                     onSuccess();             }         }         //开始发送         xhr.send(fd);     } }

后台代码:
 

/// <summary> /// upload2 的摘要说明 /// </summary> public class upload2 : IHttpHandler {     LogHelper.LogHelper _log = new LogHelper.LogHelper();     int totalCount = 0;     public void ProcessRequest(HttpContext context)     {         HttpContext _Context = context;         //接收文件         HttpRequest req = _Context.Request;         if (req.Files.Count <= 0)         {             WriteStr("获取服务器上传文件失败");             return;         }         HttpPostedFile _file = req.Files[0];         //获取参数         // string ext = req.Form["extention"];         string filename = req.Form["filename"];         //如果是int 类型当文件大的时候会出问题 最大也就是 1.9999999990686774G         int loaded = Convert.ToInt32(req.Form["loaded"]);         totalCount += loaded;         string newname = @"F:\JavaScript_Solution\H5Solition\H5Solition\Content\TempFile\";         newname += filename;         //接收二级制数据并保存         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 = new FileStream(newname, FileMode.Append, FileAccess.Write, FileShare.Read, 1024);         try         {             fs.Write(dataOne, 0, dataOne.Length);         }         finally         {             fs.Close();             stream.Close();         }         _log.WriteLine((totalCount + dataOne.Length).ToString());         WriteStr("分段数据保存成功");     }     private void WriteStr(string str)     {         HttpContext.Current.Response.Write(str);      }     public bool IsReusable     {         get         {             return true;         }     }

2.分段读取文件为blob ,并使用ajax上传到服务器,追加中止、继续功能操作

<div class="container">     <div class="panel panel-default">         <div class="panel-heading">分段读取文件:</div>         <div class="panel-body">             <input type="file" id="file" />             <br />             <input type="button" value="中止" onclick="stop();" />&emsp;             <input type="button" value="继续" onclick="containue();" />             <br />             <progress id="progressOne" max="100" value="0" style="width:400px;"></progress>             <blockquote id="Status" style="word-break:break-all;"></blockquote>         </div>     </div> </div>

JS:

/* * 分段读取文件为blob ,并使用ajax上传到服务器 * 使用Ajax方式提交上传数据文件大小应该有限值,最好500MB以内 * 原因短时间过多的ajax请求,Asp.Net后台会崩溃获取上传的分块数据为空 * 取代方式,长连接或WebSocket */ var fileBox = document.getElementById('file'); var reader = null;  //读取操作对象 var step = 1024 * 1024 * 3.5;  //每次读取文件大小 var cuLoaded = 0; //当前已经读取总数 var file = null; //当前读取的文件对象 var enableRead = true;//标识是否可以读取文件 fileBox.onchange = function () {     //获取文件对象     file = this.files[0];     var total = file.size;     console.info("文件大小:" + file.size);     var startTime = new Date();     reader = new FileReader();     //读取一段成功     reader.onload = function (e) {         //处理读取的结果         var result = reader.result;         var loaded = e.loaded;         if (enableRead == false)             return false;         //将分段数据上传到服务器         uploadFile(result, cuLoaded, function () {             console.info('loaded:' + cuLoaded + '----current:' + loaded);             //如果没有读完,继续             cuLoaded += loaded;             if (cuLoaded < total) {                 readBlob(cuLoaded);             } else {                 console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);                 cuLoaded = total;             }             //显示结果进度             var percent = (cuLoaded / total) * 100;             document.getElementById('Status').innerText = percent;             document.getElementById('progressOne').value = percent;         });     }     //开始读取     readBlob(0);     //关键代码上传到服务器     function uploadFile(result, startIndex, onSuccess) {         var blob = new Blob([result]);         //提交到服务器         var fd = new FormData();         fd.append('file', blob);         fd.append('filename', file.name);         fd.append('loaded', startIndex);         var xhr = new XMLHttpRequest();         xhr.open('post', '../ashx/upload2.ashx', true);         xhr.onreadystatechange = function () {             if (xhr.readyState == 4 && xhr.status == 200) {                 if (onSuccess)                     onSuccess();             } else if (xhr.status == 500) {                 //console.info('请求出错,' + xhr.responseText);                 setTimeout(function () {                     containue();                 }, 1000);             }         }         //开始发送         xhr.send(fd);     } } //指定开始位置,分块读取文件 function readBlob(start) {     //指定开始位置和结束位置读取文件     var blob = file.slice(start, start + step);     reader.readAsArrayBuffer(blob); } //中止 function stop() {     //中止读取操作     console.info('中止,cuLoaded:' + cuLoaded);     enableRead = false;     reader.abort(); } //继续 function containue() {     console.info('继续,cuLoaded:' + cuLoaded);     enableRead = true;     readBlob(cuLoaded); }

后台代码同上

3.分段读取文件为二进制数组 ,并使用ajax上传到服务器

 使用二进制数组传递的方式,效率特别低,最终文件还与原始大小有些偏差

HTML内容同上

JS:

/*     * 分段读取文件为二进制数组 ,并使用ajax上传到服务器     * 使用二进制数组传递的方式,效率特别低,最终文件还与原始大小有些偏差     */ var fileBox = document.getElementById('file'); var reader = new FileReader(); //读取操作对象 var step = 1024 * 1024;  //每次读取文件大小 var cuLoaded = 0; //当前已经读取总数 var file = null; //当前读取的文件对象 var enableRead = true;//标识是否可以读取文件 fileBox.onchange = function () {     //获取文件对象     if (file == null) //如果赋值多次会有丢失数据的可能         file = this.files[0];     var total = file.size;     console.info("文件大小:" + file.size);     var startTime = new Date();     //读取一段成功     reader.onload = function (e) {         //处理读取的结果         var result = reader.result;         var loaded = e.loaded;         if (enableRead == false)             return false;         //将分段数据上传到服务器         uploadFile(result, cuLoaded, function () {             console.info('loaded:' + cuLoaded + '----current:' + loaded);             //如果没有读完,继续             cuLoaded += loaded;             if (cuLoaded < total) {                 readBlob(cuLoaded);             } else {                 console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);                 cuLoaded = total;             }             //显示结果进度             var percent = (cuLoaded / total) * 100;             document.getElementById('Status').innerText = percent;             document.getElementById('progressOne').value = percent;         });     }     //开始读取     readBlob(0);     //关键代码上传到服务器     function uploadFile(result, startIndex, onSuccess) {         var array = new Int8Array(result);         console.info(array.byteLength);         //提交到服务器         var fd = new FormData();         fd.append('file', array);         fd.append('filename', file.name);         fd.append('loaded', startIndex);         var xhr = new XMLHttpRequest();         xhr.open('post', '../ashx/upload3.ashx', true);         xhr.onreadystatechange = function () {             if (xhr.readyState == 4 && xhr.status == 200) {                 // console.info(xhr.responseText);                 if (onSuccess)                     onSuccess();             } else if (xhr.status == 500) {                 console.info('服务器出错');                 reader.abort();             }         }         //开始发送         xhr.send(fd);     } } //指定开始位置,分块读取文件 function readBlob(start) {     //指定开始位置和结束位置读取文件     var blob = file.slice(start, start + step);     reader.readAsArrayBuffer(blob); } //中止 function stop() {     //中止读取操作     console.info('中止,cuLoaded:' + cuLoaded);     enableRead = false;     reader.abort(); } //继续 function containue() {     console.info('继续,cuLoaded:' + cuLoaded);     enableRead = true;     readBlob(cuLoaded); }

后台代码:

/// <summary> /// upload3 的摘要说明 /// </summary> public class upload3 : IHttpHandler {     LogHelper.LogHelper _log = new LogHelper.LogHelper();     int totalCount = 0;     public void ProcessRequest(HttpContext context)     {         HttpContext _Context = context;         //接收文件         HttpRequest req = _Context.Request;         string data = req.Form["file"];         //转换方式一         //int[] intData = data.Split(',').Select(q => Convert.ToInt32(q)).ToArray();         //byte[] dataArray = intData.ToList().ConvertAll(x=>(byte)x).ToArray();         //转换方式二         byte[] dataArray = data.Split(',').Select(q => int.Parse(q)).Select(q => (byte)q).ToArray();         //获取参数         string filename = req.Form["filename"];         //如果是int 类型当文件大的时候会出问题 最大也就是 1.9999999990686774G         int loaded = Convert.ToInt32(req.Form["loaded"]);         totalCount += loaded;         string newname = @"F:\JavaScript_Solution\H5Solition\H5Solition\Content\TempFile\";         newname += filename;         try         {             // 接收二级制数据并保存             byte[] dataOne = dataArray;             FileStream fs = new FileStream(newname, FileMode.Append, FileAccess.Write, FileShare.Read, 1024);             try             {                 fs.Write(dataOne, 0, dataOne.Length);             }             finally             {                 fs.Close();             }             _log.WriteLine((totalCount + dataOne.Length).ToString());             WriteStr("分段数据保存成功");         }         catch (Exception ex)         {             throw ex;         }     }     private void WriteStr(string str)     {         HttpContext.Current.Response.Write(str);     }     public bool IsReusable     {         get         {             return false;         }     } }

关于“HTML5中文件域+FileReader如何分段读取文件并上传到服务器”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI