HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket
一、单文件上传实例
HTML:
<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();" />∅
<input type="button" value="继续" onclick="containue();" />
<progress id="progressOne" style="width:400px;" max="100" value="0"></progress>
<blockquote id="Status" style="word-break:break-all;"></blockquote>
</div>
</div>
</div>
JS:
/*
* 测试WebSocket上传
* 本地浏览器上传速度测试单个文件,上传速度IE>FF>Google(Google浏览器慢相当多)
*/
var fileBox = document.getElementById('file');
var reader = null; //读取操作对象
var step = 1024 * 256; //每次读取文件大小 ,字节数
var cuLoaded = 0; //当前已经读取总数
var file = null; //当前读取的文件对象
var enableRead = true;//标识是否可以读取文件
var total = 0; //记录当前文件总字节数
var startTime = null; //标识开始上传时间
fileBox.onchange = function () {
//获取文件对象
file = this.files[0];
total = file.size;
console.info("文件大小:" + file.size);
if (ws == null) {
if (window.confirm('建立与服务器链接失败,确定重试链接吗')) {
createSocket(function () {
bindReader();
});
}
return;
}
bindReader();
}
//绑定reader
function bindReader() {
cuLoaded = 0;
startTime = new Date();
enableRead = true;
reader = new FileReader();
//读取一段成功
reader.onload = function (e) {
console.info('读取总数:' + e.loaded);
if (enableRead == false)
return false;
//根据当前缓冲区来控制客户端读取速度
if (ws.bufferedAmount > step * 10) {
setTimeout(function () {
//继续读取
console.log('--------------》进入等待');
loadSuccess(e.loaded);
}, 3);
} else {
//继续读取
loadSuccess(e.loaded);
}
}
//开始读取
readBlob();
}
//读取文件成功处理
function loadSuccess(loaded) {
//将分段数据上传到服务器
var blob = reader.result;
//使用WebSocket 服务器发送数据
if (cuLoaded == 0) //发送文件名
ws.send(file.name);
ws.send(blob);
//如果没有读完,继续
cuLoaded += loaded;
if (cuLoaded < total) {
readBlob();
} else {
console.log('总共上传:' + cuLoaded + ',总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);
}
//显示结果进度
var percent = (cuLoaded / total) * 100;
document.getElementById('Status').innerText = percent;
document.getElementById('progressOne').value = percent;
}
//指定开始位置,分块读取文件
function readBlob() {
//指定开始位置和结束位置读取文件
var blob = file.slice(cuLoaded, cuLoaded + step);
reader.readAsArrayBuffer(blob);
}
//中止
function stop() {
//中止读取操作
console.info('中止,cuLoaded:' + cuLoaded);
enableRead = false;
reader.abort();
}
//继续
function containue() {
console.info('继续,cuLoaded:' + cuLoaded);
enableRead = true;
readBlob();
}
var ws = null;
//创建和服务器的WebSocket 链接
function createSocket(onSuccess) {
var url = 'ws://localhost:55373/ashx/upload3.ashx';
ws = new WebSocket(url);
ws.onopen = function () {
console.log('connected成功');
if (onSuccess)
onSuccess();
}
ws.onmessage = function (e) {
var data = e.data;
if (isNaN(data) == false) {
//console.log('当前上传成功:' + data);
} else {
console.info(data);
}
}
ws.onclose = function (e) {
//中止客户端读取
stop();
console.log('链接断开');
}
ws.onerror = function (e) {
//中止客户端读取
stop();
console.info(e);
console.log('传输中发生异常');
}
}
//页面加载完建立链接
createSocket();
服务器后台处理:
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 = "";
//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);
//判断用户传入的类型进行处理
if (result.MessageType == WebSocketMessageType.Text)
{
string msg = Encoding.UTF8.GetString(buffer.Array, , curLength);
filename = msg;
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes("接收文件名成功:" + filename));
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else if (result.MessageType == WebSocketMessageType.Binary)
{
//创建并保存文件,如果上传成功,返回当前接收到的文件大小
string msg = SaveFile(filename, buffer, curLength);
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
else { break; }
}
}
/// <summary>
/// 追加二进制数据到文件
/// </summary>
public string SaveFile(string file, ArraySegment<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, , Length);
}
finally
{
fs.Close();
}
return "保存文件成功";
}
catch (Exception ex)
{
return ex.Message;
}
}
本地浏览器上传速度测试单个文件,上传速度IE>FF>Google(Google浏览器慢相当多)
原因:每次send发送数据的时候Google浏览器发送的数据量相对较小
分段读取文件(四):http://www.cnblogs.com/tianma3798/p/5839869.html
读取文件三:http://www.cnblogs.com/tianma3798/p/5839810.html
HTML5 文件域+FileReader 分段读取文件并上传(七)-WebSocket的更多相关文章
- HTML5 文件域+FileReader 分段读取文件并上传(八)-WebSocket
一.同时上传多个文件处理 HTML: <div class="container"> <div class="panel panel-default&q ...
- 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里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...
随机推荐
- 提升网站用户体验—WebP 图片的高效使用
一.WebP 的由来 现代图像压缩技术对我们的生活方式影响很大.数码相机能将上千张高质量图片存储到一张内存卡里.智能手机可以与邻近设备快速分享高分辨率的图片.网站与手机等移动设备能快速展示各种富媒体. ...
- 【HDU4552】 怪盗基德的挑战书(后缀数组)
怪盗基德的挑战书 Problem Description “在树最美丽的那天,当时间老人再次把大钟平均分开时,我会降临在灯火之城的金字塔前,带走那最珍贵的笑容.”这是怪盗基德盗取巴黎卢浮宫的<蒙 ...
- QT的父子Widget之间消息的传递(如果子类没有accept或ignore该事件,则该事件会被传递给其父亲——Qlabel与QPushButton的处理就不一样)
以前我一直以为:在父widget上摆一个子widget后,当click子widget时:只会进入到子widget的相关事件处理函数中,比如进入到mousePressEvent()中, 而不会进入到父w ...
- 一些记录查询的SQL语句
-- ======================== 第三天 =========================== CREATE DATABASE php0408 CHARSET utf8 ;CR ...
- android5.0中RecycleView的用法
最近学习了android5.0中新增的一个组件RecycleView,是用来代替当前的listview开发的,是因为在RecycleView中已经有了viewholder缓存,并且不同的item之间可 ...
- C++ Prime:switch内部的变量定义
如果需要为某个case分支定义并初始化一个变量,我们应该把变量定义在块内,从而确保后面的所有case标签都在变量的作用域之外. case true: { // 正确,声明语句位于语句块内部 strin ...
- Win7 64位系统U盘安装Centos6.5双系统
(win764位旗舰版系统 Centos6.5亲测成功) 安装前准备: U盘.软碟通(UltraISO).CentOS-6.5-x86_64-bin-DVD1(DVD 2只是一些软件,安装系统只要DV ...
- lingo运筹学上机实验指导
<运筹学上机实验指导>分为两个部分,第一部分12学时,是与运筹学理论课上机同步配套的4个实验(线性规划.灵敏度分析.运输问题与指派问题.最短路问题和背包问题)的Excel.LONGO和LI ...
- 软中断与硬中断 & 中断抢占 中断嵌套
参考了这篇文章:http://blog.csdn.net/zhangskd/article/details/21992933 从本质上来讲,中断是一种电信号,当设备有某种事件发生时,它就会产生中断,通 ...
- Java生成缩略图Thumbnailator(转载)
转自(http://rensanning.iteye.com/blog/1545708) Thumbnailator 是一个为Java界面更流畅的缩略图生成库.从API提供现有的图像文件和图像对象的缩 ...