首页 > 代码库 > HTML5 文件域+FileReader 分段读取文件并上传(八)-WebSocket

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 =http://www.mamicode.com/ 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;})();
View Code

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[1024 * 256 * 2];//缓存接收文件        //Array.Copy        //byte[] bufferAll = new byte[];        int loaded = 0;  //当前缓冲数量        //2.监视相应        while (true)        {            /*                * 此处缓存数组指定读取客户端数据的长度                * 如果客户端发送数据超过当前缓存区,则会读取多次                */            ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024 * 256]);            //接收客户端信息            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, 0, curLength);                        if (msg == "发送完成")                        {                            //发送完成,全部写入文件                            string str = SaveFile(filename, bufferAll, loaded);                            loaded = 0;                            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, 0, bufferAll, 0, 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, 0, 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, 0, Length);            }            finally            {                fs.Close();            }            return "保存文件成功";        }        catch (Exception ex)        {            return ex.Message;        }    }
View Code

运行结果显示:

技术分享

分段上传文件(七):http://www.cnblogs.com/tianma3798/p/5852475.html

分段上传文件(六):http://www.cnblogs.com/tianma3798/p/5845291.html
分段读取文件(五):http://www.cnblogs.com/tianma3798/p/5841584.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源代码:

http://git.oschina.net/tiama3798/HTML5Demo/tree/WebSocket/

http://git.oschina.net/tiama3798/HTML5Demo/tree/FileReader/

HTML5 文件域+FileReader 分段读取文件并上传(八)-WebSocket