使用Html5的WebSocket在浏览器上传文件, 支持多文件和大文件.
来源:互联网 发布:jsp数据展示样式 编辑:程序博客网 时间:2024/06/11 22:45
使用Html5的WebSocket在浏览器上传文件, 支持多文件和大文件.
使用websocket上传文件的简单例子: 使用Html5的WebSocket在浏览器上传文件
上篇文章没有解决的问题就是大文件的上传问题, 而且多文件上传问题也未协调. 所以这篇文章就是解决这两个问题的.
如果将一个大文件直接读入内存再发送的话, 内存会吃不消, 所以我们把大文件分块传输. Html5的Fileread方法提供了读取文件部分内容Blob的方法.
为了保证后台接收到的分块数据的顺序不会乱掉, 我们需要后台确定写入分块数据后再发送下一块数据.
在Html端:
<!DOCTYPE html><html><head><title>WebSocket Chat Client</title><meta charset="utf-8" /><script type="text/javascript" src="jquery-1.6.4.min.js"></script><script type="text/javascript" src="jquery.json-2.3.min.js"></script><script type="text/javascript"> $().ready( function() { // Check for the various File API support. if (window.File && window.FileReader && window.FileList && window.Blob) { // Great success! All the File APIs are supported. } else { alert('The File APIs are not fully supported in this browser.'); } }); //在消息框中打印内容 function log(text) { $("#log").append(text+"\n"); } //全局的websocket变量
var ws; var paragraph = 10485760; var fileList ; var file; var startSize,endSize = 0; var i = 0; j = 0; //连接服务器 $(function() { $("#connect").click(function() { ws = new WebSocket($("#uri").val()); //连接成功建立后响应 ws.onopen = function() { log("成功连接到" + $("#uri").val()); } //收到服务器消息后响应 ws.onmessage = function(e) { log("服务器说" + e.data + (e.data=="ok")); if(e.data == "ok"){ if(endSize < file.size){ startSize = endSize; endSize += paragraph ; if (file.webkitSlice) { var blob = file.webkitSlice(startSize, endSize); } else if (file.mozSlice) { var blob = file.mozSlice(startSize, endSize); } var reader = new FileReader(); reader.readAsArrayBuffer(blob); reader.onload = function loaded(evt) { var ArrayBuffer = evt.target.result; log("发送文件第" + (i++) + "部分"); ws.send(ArrayBuffer); } } else{ startSize = endSize = 0; i = 0; log("发送" + file.name +"完毕"); file = fileList[j++]; if(file.name){ ws.send(file.name); } log("发送文件完毕"); } } //连接关闭后响应 ws.onclose = function() { log("关闭连接"); ws = null; } return false; } }); }); $(function() { $("#sendFileForm").click(function() { fileList = document.getElementById("file").files; file = fileList[0]; ws.send(file.name); }) }); $(function() { $("#reset").click(function() { $("#log").empty(); return false; }); }); </script></head><body> <span>Html5功能测试</span> <span id="progress">0</span><br> <input type="text" id="uri" value="ws://localhost:8887" style="width: 200px;"> <input type="button" id="connect" value="Connect"><input type="button" id="disconnect" value="Disconnect" disabled="disabled"> <form > <input id="file" type="file" multiple /> <input type="button" id="sendFileForm" value="测试" /> <input type="button" id="reset" value="清空消息框" /> </form> <form> <textarea id="log" rows="30" cols="100" style="font-family: monospace; color: red;"></textarea> </form></body></html>
这里设置了文件大于paragraph (10M)时就会分块发送文件.
服务器端:
/*** 处理字符串消息*/public void onMessage( WebSocket conn, String message ) { System.out.println("文件名" + message); //将文件名写入连接对象中,(需要手动修改webSocket类) conn.setFileName(message); try { conn.send("ok"); } catch (NotYetConnectedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
/*** 处理二进制消息*/ public void onMessage(WebSocket conn, byte[] message) { System.out.println("收到二进制流:"); //将二进制流保存为文件, 文件名从连接对象中取出 saveFileFromBytes(message, "src/" + conn.getFileName()); //告诉前台可以继续发送了. try { conn.send("ok"); } catch (NotYetConnectedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 将二进制byte[]数组写入文件中 * @param b byte[]数组 * @param outputFile 文件位置 * @return 成功: true 失败: false */ public static boolean saveFileFromBytes(byte[] b, String outputFile) { FileOutputStream fstream = null; File file = null; try { file = new File(outputFile); fstream = new FileOutputStream(file, true); fstream.write(b); } catch (Exception e) { e.printStackTrace(); return false; } finally { if (fstream != null) { try { fstream.close(); } catch (IOException e1) { e1.printStackTrace(); } } } return true; }
好了, 顺序发送保证了后台写入的数据也是顺序的, 文件就不会出错了! 搞定!
- 使用Html5的WebSocket在浏览器上传文件, 支持多文件和大文件.
- 使用Html5的WebSocket在浏览器上传文件
- 使用Html5的WebSocket在浏览器上传文件
- 使用Html5的WebSocket在浏览器上传文件
- HTML5-WebSocket实现多文件同时上传
- HTML5-WebSocket实现多文件同时上传
- 用html5的websocket实现的文件上传,支持断点续传,妙传。
- 多文件上传插件Stream,解决不同浏览器上传文件的插件,是Uploadify的Flash版和Html5版的结合,带进度条,并支持html5断点续传,拖拽等功能
- html5大文件上传技术
- html5 大文件断点上传
- html5大文件上传技术
- 浏览器上传大文件的尴尬
- HTML5 文件域+FileReader 分段读取文件并上传-WebSocket
- Html5的文件上传
- html5上传文件和html4上传文件的区别
- html5上传文件,Firefox支持重复选择同一文件,其它浏览器不支持
- html5多文件上传
- 使用html5技术实现文件的上传
- Linux命令之cut
- LINK : fatal error LNK1104: 无法打开文件“uiAccess='false' /DEBUG /PDB: 问题的解决方案
- Spring Security加密策略
- 计算机英语复习题
- linux环境下(SUSE 11)安装ArcSDE 10.0 的注意事项(Oracle 11g)
- 使用Html5的WebSocket在浏览器上传文件, 支持多文件和大文件.
- 面向服务开发的优点
- linux编程之main()函数启动过程
- CSS选择器
- 多例模式
- Java内存模型——原子性
- CentOS6.3+JDK7+Tomcat7.0+MySQL5.5 开发环境的搭建
- Spatialite的学习资料
- 如何成为一个合法的iOS开发者