您好,欢迎访问一九零五行业门户网

html5中文件域+FileReader分段读取文件并上传到服务器的案例

1.简单分段读取文件为blob,ajax上传到服务器
<p class="container"> <p class="panel panel-default"> <p class="panel-heading">分段读取文件:</p> <p class="panel-body"> <input type="file" id="file" /> <blockquote style="word-break:break-all;"></blockquote> </p> </p> </p>
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上传到服务器,追加中止、继续功能操作
<p class="container"> <p class="panel panel-default"> <p class="panel-heading">分段读取文件:</p> <p 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> </p> </p> </p>
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; } } }
说明:使用ajax方式上传,文件不能过大,最好小于三四百兆,因为过多的连续ajax请求会使后台崩溃,获取inputstream中数据会为空,尤其在google浏览器测试过程中。
以上就是html5中文件域+filereader分段读取文件并上传到服务器的案例的详细内容。
其它类似信息

推荐信息