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

谁借莪1个温暖的怀抱¢ 2024-02-18 21:24 113阅读 0赞

一、同时上传多个文件处理

HTML:

复制代码

  1. <div class="container">
  2. <div class="panel panel-default">
  3. <div class="panel-heading">分段读取文件:</div>
  4. <div class="panel-body" id="bodyOne">
  5. <input type="file" id="file" multiple/><br />
  6. </div>
  7. </div>
  8. </div>

复制代码

JS:

1.封装单文上传实例

ExpandedBlockStart.gif

复制代码

  1. //封装 单个文件上传实例
  2. (function () {
  3. var url = 'ws://localhost:55373/ashx/upload4.ashx';
  4. //指定上传文件,创建上传操作对象
  5. function uploadOperate(file) {
  6. var _this = this;
  7. this.reader = new FileReader();//读取文件对象
  8. this.step = 1024 * 256;//每次读取文件字节数
  9. this.curLoaded = 0; //当前读取位置
  10. this.file = file; //当前文件对象
  11. this.enableRead = true; //指定是否可读取,
  12. this.total = file.size; //当前文件总大小
  13. this.startTime = new Date(); //开始读取时间
  14. //创建显示
  15. this.createItem();
  16. this.initWebSocket(function () {
  17. _this.bindReader();
  18. });
  19. console.info('文件大小:' + this.total);
  20. }
  21. uploadOperate.prototype = {
  22. //绑定读取事件
  23. bindReader: function () {
  24. var _this = this;
  25. var reader = this.reader;
  26. var ws = this.ws;
  27. reader.onload = function (e) {
  28. //判断是否能再次读取
  29. if (_this.enableRead == false) return;
  30. //根据当前缓冲区 控制读取速度
  31. if (ws.bufferedAmount >= _this.step * 20) {
  32. setTimeout(function () {
  33. _this.loadSuccess(e.loaded);
  34. }, 5);
  35. console.info('---->进入等待');
  36. } else {
  37. _this.loadSuccess(e.loaded);
  38. }
  39. }
  40. //开始读取
  41. _this.readBlob();
  42. },
  43. //读取成功,操作处理
  44. loadSuccess: function (loaded) {
  45. var _this = this;
  46. var ws = _this.ws;
  47. //使用WebSocket 将二进制输出上传到服务器
  48. var blob = _this.reader.result;
  49. if (_this.curLoaded <= 0)
  50. ws.send(_this.file.name);
  51. ws.send(blob);
  52. //当前发送完成,继续读取
  53. _this.curLoaded += loaded;
  54. if (_this.curLoaded < _this.total) {
  55. _this.readBlob();
  56. } else {
  57. //发送读取完成
  58. ws.send('发送完成');
  59. //读取完成
  60. console.log('总共上传:' + _this.curLoaded + ',总共用时:' + (new Date().getTime() - _this.startTime.getTime()) / 1000);
  61. }
  62. //显示进度等
  63. _this.showProgress();
  64. },
  65. //创建显示项
  66. createItem: function () {
  67. var _this = this;
  68. var blockquote = document.createElement('blockquote');
  69. var abort = document.createElement('input');
  70. abort.type = 'button';
  71. abort.value = '中止';
  72. abort.onclick = function () {
  73. _this.stop();
  74. };
  75. blockquote.appendChild(abort);
  76. var containue = document.createElement('input');
  77. containue.type = 'button';
  78. containue.value = '继续';
  79. containue.onclick = function () {
  80. _this.containue();
  81. };
  82. blockquote.appendChild(containue);
  83. var progress = document.createElement('progress');
  84. progress.style.width = '400px';
  85. progress.max = 100;
  86. progress.value = 0;
  87. blockquote.appendChild(progress);
  88. _this.progressBox = progress;
  89. var status = document.createElement('p');
  90. status.id = 'Status';
  91. blockquote.appendChild(status);
  92. _this.statusBox = status;
  93. document.getElementById('bodyOne').appendChild(blockquote);
  94. },
  95. //显示进度
  96. showProgress: function () {
  97. var _this = this;
  98. var percent = (_this.curLoaded / _this.total) * 100;
  99. _this.progressBox.value = percent;
  100. _this.statusBox.innerHTML = percent;
  101. },
  102. //执行读取文件
  103. readBlob: function () {
  104. var blob = this.file.slice(this.curLoaded, this.curLoaded + this.step);
  105. this.reader.readAsArrayBuffer(blob);
  106. },
  107. //中止读取
  108. stop: function () {
  109. this.enableRead = false;
  110. this.reader.abort();
  111. console.log('读取中止,curLoaded:' + this.curLoaded);
  112. },
  113. //继续读取
  114. containue: function () {
  115. this.enableRead = true;
  116. this.readBlob();
  117. console.log('读取继续,curLoaded:' + this.curLoaded);
  118. },
  119. //初始化 绑定创建连接
  120. initWebSocket: function (onSuccess) {
  121. var _this = this;
  122. var ws = this.ws = new WebSocket(url); //初始化上传对象
  123. ws.onopen = function () {
  124. console.log('connect创建成功');
  125. if (onSuccess)
  126. onSuccess();
  127. }
  128. ws.onmessage = function (e) {
  129. var data = e.data;
  130. if (isNaN(data) == false) {
  131. console.info('后台接收成功:' + data);
  132. } else {
  133. console.info(data);
  134. }
  135. }
  136. ws.onclose = function (e) {
  137. //中止读取
  138. _this.stop();
  139. console.log('connect已经断开');
  140. }
  141. ws.onerror = function (e) {
  142. //中止读取
  143. _this.stop();
  144. console.log('发生异常:' + e.message);
  145. }
  146. }
  147. };
  148. window.uploadOperate = uploadOperate;
  149. })();

复制代码

2.绑定页面处理

复制代码

  1. /*
  2. * 测试WebSocket多文件上传
  3. * 上传速度取决于 每次send() 的数据大小 ,Google之所以相对比较慢,是因为每次send的数据量太小
  4. */
  5. var fileBox = document.getElementById('file');
  6. fileBox.onchange = function () {
  7. var files = this.files;
  8. for (var i = 0; i < files.length; i++) {
  9. var file = files[i];
  10. var operate = new uploadOperate(file);
  11. }
  12. }

复制代码

服务器后台封装处理:

ExpandedBlockStart.gif

复制代码

  1. public void ProcessRequest(HttpContext context)
  2. {
  3. //处理WebSocket 请求
  4. context.AcceptWebSocketRequest(DoWork);
  5. }
  6. /// <summary>
  7. /// 委托处理函数定义
  8. /// </summary>
  9. /// <param name="context">当前WebSocket上下文</param>
  10. /// <returns></returns>
  11. public async Task DoWork(AspNetWebSocketContext context)
  12. {
  13. //1.获取当前WebSocket 对象
  14. WebSocket socket = context.WebSocket;
  15. string filename = "";
  16. byte[] bufferAll = new byte[1024 * 256 * 2];//缓存接收文件
  17. //Array.Copy
  18. //byte[] bufferAll = new byte[];
  19. int loaded = 0; //当前缓冲数量
  20. //2.监视相应
  21. while (true)
  22. {
  23. /*
  24. * 此处缓存数组指定读取客户端数据的长度
  25. * 如果客户端发送数据超过当前缓存区,则会读取多次
  26. */
  27. ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024 * 256]);
  28. //接收客户端信息
  29. CancellationToken token;
  30. WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
  31. if (socket.State == WebSocketState.Open)
  32. {
  33. //判断是否已经到了最后
  34. int curLength = Math.Min(buffer.Array.Length, result.Count);
  35. try
  36. {
  37. //判断用户传入的类型进行处理
  38. if (result.MessageType == WebSocketMessageType.Text)
  39. {
  40. string msg = Encoding.UTF8.GetString(buffer.Array, 0, curLength);
  41. if (msg == "发送完成")
  42. {
  43. //发送完成,全部写入文件
  44. string str = SaveFile(filename, bufferAll, loaded);
  45. loaded = 0;
  46. ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
  47. await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
  48. }
  49. else
  50. {
  51. filename = msg;
  52. msg = string.Format("服务器链接数量:{0},当前链接ID={1},接收文件名:{2}",
  53. AspNetWebSocketContext.ConnectionCount, context.AnonymousID, filename);
  54. ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
  55. await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
  56. }
  57. }
  58. else if (result.MessageType == WebSocketMessageType.Binary)
  59. {
  60. var temp = loaded + curLength;
  61. if ((temp) > bufferAll.Length)
  62. {
  63. //先写入文件
  64. string msg = SaveFile(filename, bufferAll, loaded);
  65. //添加到缓冲区
  66. Array.Copy(buffer.Array, 0, bufferAll, 0, curLength);
  67. loaded = curLength;
  68. //返回相应
  69. ArraySegment<byte> echor = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
  70. await socket.SendAsync(echor, WebSocketMessageType.Text, true, CancellationToken.None);
  71. }
  72. else
  73. {
  74. //添加到缓冲区
  75. Array.Copy(buffer.Array, 0, bufferAll, loaded, curLength);
  76. loaded = temp;
  77. }
  78. }
  79. }
  80. catch (Exception ex)
  81. {
  82. }
  83. }
  84. else { break; }
  85. }
  86. }
  87. /// <summary>
  88. /// 追加二进制数据到文件
  89. /// </summary>
  90. public string SaveFile(string file, byte[] buffer, int Length)
  91. {
  92. //去除文件名中的前后空格
  93. file = file.Trim();
  94. string fullname = @"F:\JavaScript_Solution\H5Solition\UploadWebForm\content\" + file;
  95. try
  96. {
  97. FileStream fs = new FileStream(fullname, FileMode.Append, FileAccess.Write);
  98. try
  99. {
  100. //byte[] result = buffer.ToArray();
  101. //fs.Write(result, 0, Length);
  102. fs.Write(buffer, 0, Length);
  103. }
  104. finally
  105. {
  106. fs.Close();
  107. }
  108. return "保存文件成功";
  109. }
  110. catch (Exception ex)
  111. {
  112. return ex.Message;
  113. }
  114. }

复制代码

运行结果显示:

470800-20160908114452769-1069805538.png

更多Demo源代码:

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

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

发表评论

表情:
评论列表 (有 0 条评论,113人围观)

还没有评论,来说两句吧...

相关阅读