HTML5 文件域+FileReader 分段读取文件并上传(八)-WebSocket
一、同时上传多个文件处理
HTML:
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">分段读取文件:</div>
<div class="panel-body" id="bodyOne">
<input type="file" id="file" multiple/><br />
</div>
</div>
</div>
JS:
1.封装单文上传实例
//封装 单个文件上传实例
(function () {
var url = 'ws://localhost:55373/ashx/upload4.ashx';
//指定上传文件,创建上传操作对象
function uploadOperate(file) {
var _this = this;
this.reader = new FileReader();//读取文件对象
this.step = 1024 * 256;//每次读取文件字节数
this.curLoaded = 0; //当前读取位置
this.file = file; //当前文件对象
this.enableRead = true; //指定是否可读取,
this.total = file.size; //当前文件总大小
this.startTime = new Date(); //开始读取时间
//创建显示
this.createItem();
this.initWebSocket(function () {
_this.bindReader();
});
console.info('文件大小:' + this.total);
}
uploadOperate.prototype = {
//绑定读取事件
bindReader: function () {
var _this = this;
var reader = this.reader;
var ws = this.ws;
reader.onload = function (e) {
//判断是否能再次读取
if (_this.enableRead == false) return;
//根据当前缓冲区 控制读取速度
if (ws.bufferedAmount >= _this.step * 20) {
setTimeout(function () {
_this.loadSuccess(e.loaded);
}, 5);
console.info('---->进入等待');
} else {
_this.loadSuccess(e.loaded);
}
}
//开始读取
_this.readBlob();
},
//读取成功,操作处理
loadSuccess: function (loaded) {
var _this = this;
var ws = _this.ws;
//使用WebSocket 将二进制输出上传到服务器
var blob = _this.reader.result;
if (_this.curLoaded <= 0)
ws.send(_this.file.name);
ws.send(blob);
//当前发送完成,继续读取
_this.curLoaded += loaded;
if (_this.curLoaded < _this.total) {
_this.readBlob();
} else {
//发送读取完成
ws.send('发送完成');
//读取完成
console.log('总共上传:' + _this.curLoaded + ',总共用时:' + (new Date().getTime() - _this.startTime.getTime()) / 1000);
}
//显示进度等
_this.showProgress();
},
//创建显示项
createItem: function () {
var _this = this;
var blockquote = document.createElement('blockquote');
var abort = document.createElement('input');
abort.type = 'button';
abort.value = '中止';
abort.onclick = function () {
_this.stop();
};
blockquote.appendChild(abort); var containue = document.createElement('input');
containue.type = 'button';
containue.value = '继续';
containue.onclick = function () {
_this.containue();
};
blockquote.appendChild(containue); var progress = document.createElement('progress');
progress.style.width = '400px';
progress.max = 100;
progress.value = 0;
blockquote.appendChild(progress);
_this.progressBox = progress; var status = document.createElement('p');
status.id = 'Status';
blockquote.appendChild(status);
_this.statusBox = status; document.getElementById('bodyOne').appendChild(blockquote);
},
//显示进度
showProgress: function () {
var _this = this;
var percent = (_this.curLoaded / _this.total) * 100;
_this.progressBox.value = percent;
_this.statusBox.innerHTML = percent;
},
//执行读取文件
readBlob: function () {
var blob = this.file.slice(this.curLoaded, this.curLoaded + this.step);
this.reader.readAsArrayBuffer(blob);
},
//中止读取
stop: function () {
this.enableRead = false;
this.reader.abort();
console.log('读取中止,curLoaded:' + this.curLoaded);
},
//继续读取
containue: function () {
this.enableRead = true;
this.readBlob();
console.log('读取继续,curLoaded:' + this.curLoaded);
},
//初始化 绑定创建连接
initWebSocket: function (onSuccess) {
var _this = this;
var ws = this.ws = new WebSocket(url); //初始化上传对象
ws.onopen = function () {
console.log('connect创建成功');
if (onSuccess)
onSuccess();
}
ws.onmessage = function (e) {
var data = e.data;
if (isNaN(data) == false) {
console.info('后台接收成功:' + data);
} else {
console.info(data);
}
}
ws.onclose = function (e) {
//中止读取
_this.stop();
console.log('connect已经断开');
}
ws.onerror = function (e) {
//中止读取
_this.stop();
console.log('发生异常:' + e.message);
}
}
};
window.uploadOperate = uploadOperate;
})();
2.绑定页面处理
/*
* 测试WebSocket多文件上传
* 上传速度取决于 每次send() 的数据大小 ,Google之所以相对比较慢,是因为每次send的数据量太小
*/
var fileBox = document.getElementById('file');
fileBox.onchange = function () {
var files = this.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
var operate = new uploadOperate(file);
}
}
服务器后台封装处理:
public void ProcessRequest(HttpContext context)
{
//处理WebSocket 请求
context.AcceptWebSocketRequest(DoWork);
}
/// <summary>
/// 委托处理函数定义
/// </summary>
/// <param name="context">当前WebSocket上下文</param>
/// <returns></returns>
public async Task DoWork(AspNetWebSocketContext context)
{
//1.获取当前WebSocket 对象
WebSocket socket = context.WebSocket;
string filename = "";
byte[] bufferAll = new byte[ * * ];//缓存接收文件 //Array.Copy
//byte[] bufferAll = new byte[];
int loaded = ; //当前缓冲数量
//2.监视相应
while (true)
{
/*
* 此处缓存数组指定读取客户端数据的长度
* 如果客户端发送数据超过当前缓存区,则会读取多次
*/
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[ * ]);
//接收客户端信息
CancellationToken token;
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
if (socket.State == WebSocketState.Open)
{
//判断是否已经到了最后
int curLength = Math.Min(buffer.Array.Length, result.Count);
try
{
//判断用户传入的类型进行处理
if (result.MessageType == WebSocketMessageType.Text)
{
string msg = Encoding.UTF8.GetString(buffer.Array, , curLength);
if (msg == "发送完成")
{
//发送完成,全部写入文件
string str = SaveFile(filename, bufferAll, loaded);
loaded = ;
ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
filename = msg;
msg = string.Format("服务器链接数量:{0},当前链接ID={1},接收文件名:{2}",
AspNetWebSocketContext.ConnectionCount, context.AnonymousID, filename);
ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
else if (result.MessageType == WebSocketMessageType.Binary)
{
var temp = loaded + curLength;
if ((temp) > bufferAll.Length)
{
//先写入文件
string msg = SaveFile(filename, bufferAll, loaded);
//添加到缓冲区
Array.Copy(buffer.Array, , bufferAll, , curLength);
loaded = curLength;
//返回相应
ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
//添加到缓冲区
Array.Copy(buffer.Array, , bufferAll, loaded, curLength);
loaded = temp;
}
}
}
catch (Exception ex)
{ }
}
else { break; }
}
}
/// <summary>
/// 追加二进制数据到文件
/// </summary>
public string SaveFile(string file, byte[] buffer, int Length)
{
//去除文件名中的前后空格
file = file.Trim();
string fullname = @"F:\JavaScript_Solution\H5Solition\UploadWebForm\content\" + file;
try
{
FileStream fs = new FileStream(fullname, FileMode.Append, FileAccess.Write);
try
{
//byte[] result = buffer.ToArray();
//fs.Write(result, 0, Length);
fs.Write(buffer, , Length);
}
finally
{
fs.Close();
}
return "保存文件成功";
}
catch (Exception ex)
{
return ex.Message;
}
}
运行结果显示:
分段上传文件(七):http://www.cnblogs.com/tianma3798/p/5852475.html
分段读取文件(四):http://www.cnblogs.com/tianma3798/p/5839869.html
读取文件三:http://www.cnblogs.com/tianma3798/p/5839810.html
读取文件二:http://www.cnblogs.com/tianma3798/p/5839791.html
读取文件一:http://www.cnblogs.com/tianma3798/p/4355949.html
更多Demo源代码:
HTML5 文件域+FileReader 分段读取文件并上传(八)-WebSocket的更多相关文章
- HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket
一.单文件上传实例 HTML: <div class="container"> <div class="panel panel-default" ...
- HTML5 文件域+FileReader 分段读取文件并上传到服务器(六)
说明:使用Ajax方式上传,文件不能过大,最好小于三四百兆,因为过多的连续Ajax请求会使后台崩溃,获取InputStream中数据会为空,尤其在Google浏览器测试过程中. 1.简单分段读取文件为 ...
- HTML5 文件域+FileReader 分段读取文件(五)
一.默认FileReader会分段读取File对象,这是分段大小不一定,并且一般会很大 HTML: <div class="container"> <!--文本文 ...
- HTML5 文件域+FileReader 分段读取文件(四)
一.分段读取txt文本 HTML: <div class="container"> <div class="panel panel-default&qu ...
- html5中利用FileReader来读取文件。
利用FileReader来读取文件的能够来实现即时预览的效果,这个也是在html5中才有的功能. <!DOCTYPE html> <html lang="en"& ...
- HTML5 文件域+FileReader 读取文件(一)
在HTML5以前,HTML的文件上传域的功能具有很大的局限性,这种局限性主要体现在如下两点: 每次只能选择一个文件进行上传 客户端代码只能获取被上传文件的文件路径,无法访问实际的文件内容 一.File ...
- HTML5之fileReader异步读取文件及文件切片读取
fileReader的方法与事件 fileReade实现图片预加载 fileReade实现文件读取进度条 fileReade的与file.s实现文件切片读取 一.fileReader的方法与事件 1. ...
- 前端js怎么实现大文件G级的断点续传(分块上传)和分段下载
需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...
- Java利用内存映射文件实现按行读取文件
我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...
随机推荐
- 获取设备mac地址和md5加密
SGMSettingConfig.h #import <Foundation/Foundation.h> @interface SGMSettingConfig : NSObject{ N ...
- DIV焦点事件
div本来是没有focus和blur事件的. 如果用div来模拟一个input标签,同时需要它和input一样响应focus和blur事件, 就需要给他加上attribute:tabindex An ...
- bootcamp
为了鄙社自主研发的html5studio和mist,我给Air划了32G装windows囧 第一要注意的是,必须使用bootcamp划分将要安装windows的分区,不要在windows安装过程中删除 ...
- Tomcat默认打开项目设置
Tomcat设置默认启动项目 Tomcat设置默认启动项目,顾名思义,就是让可以在浏览器的地址栏中输入ip:8080,就能访问到我们的项目.具体操作如下: 1.打开tomcat的安装根目录,找到Tom ...
- [原]Hadoop海量视频、图像分析分布式处理总结
在刚刚入手视频图像分析时,有点不知所措,后来经过查找了很多资料.本篇文章主要叙述图像的分析处理,至于视频,实际上视频本身就是一个大文件,hadoop对于大文件处理是高效的,所以在MapReduce的处 ...
- 有关Spring Batch
在使用Spring Batch时,在无法实现StepListener的情况下,如何使用ExecutionContext呢. 解决办法,使用宣言@BeforeStep或@AfterStep.
- unity5 人皮渲染 Skin Shading
换了一种方法,优化了一下代码,unity5效果很好,消耗不大 点开可查看大图 加入了次表面散射的阴影与自阴影 ------------by wolf96 wolf_crix ...
- yarn安装部署
在HDFS HA(http://www.cnblogs.com/yinchengzhe/p/5140117.html)基础上进行yarn的安装. 1.配置yarn-site.xml 参数详情参考 ht ...
- SRM 410(1-250pt, 1-500pt)
DIV1 250pt 题意:对于图G,有一些点和边,点中有一些点称为特殊点.问在所有特殊点最终不能处于同一个联通块的条件下,最多能给在图G中添加多少条边. 解法:首先,对于图G,处理出它有哪些联通块, ...
- codeforce 230D Dijsktra
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #i ...