视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
HTML5断点续上传的示例代码分享
2020-11-27 15:10:20 责编:小采
文档


断点http://www.gxlcms.com/php/php-tp-uploads.html" target="_blank">上传,java里面比较靠谱一点的,一般都会选用Flex。我承认,Flex只是摸了一下,不精通。HTML 5 有个Blob对象(File对象继承它),这个对象有个方法slice方法,可以对一个文件进行分片。,再加上HTML 5的File API和WebStorage。做了一个段断点续传的demo。

代码比较挫,把一个文件分成一个个小片之后,每一次上传都会将已经上传的字节数放到LocalStorage里面。关于LocalStorage里面缓存怎么清,可以参看Chrome - HTML 5 本地存储。如果上传的途中暂停或者直接关掉浏览器。下次上传的时候,就会从那个节点开始上传。

PS:demo操作,请先建立WS连接之后,再选择文件上传

代码请笑纳:

<!DOCTYPE html>
<html>
<head>
 <title>使用WebSocket实现断点续传文件</title>
 <meta charset="utf-8">
</head>
<script type="text/javascript" src="demo.js"></script>
 
<body onload="init();">
<button onclick="webSocketConn();">创建连接</button>(step1)
<div class="row">
 <label for="fileToUpload">Select a File to Upload</label>
 <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>(step2)
</div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div class="row">
 <button onclick="sendFileName();uploadFile()">上传</button>(step3)
 <button onclick="pauseUpload()">暂停</button>
  <label id="progressNumber"></label>
</div>
<div id="msg" style="max-height: 400px; overflow:auto;min-height: 100px;">
</div>
</body>
</html>
####### 断点续传 ######
author:linrb
createTime: 2012-08-22
QQ: 569830404
*/
var websocket = null; //websocket
var msg = null; //日志
var paragraph = 10240; //每次分片传输文件的大小 10KB
var blob = null;// 分片数据的载体Blob对象
var file = null; //传输的文件
var startSize,endSize = 0; //分片的始终字节点
var uploadState = 0; // 0: 无上传/取消, 1: 上传中, 2: 暂停
 
//初始化消息框
function init(){
 msg = document.getElementById("msg");
}
/**
 * 分片上传文件
 */
function uploadFile() {
 if(file){
 //将上传状态设置成1
 uploadState = 1;
 endSize = getLastestUploadEndSize(file);
 var reader = new FileReader();
 reader.onload = function loaded(evt) {
 var ArrayBuffer = evt.target.result;
 websocket.send(ArrayBuffer);
 uploadProgress(endSize);
 };
 if(endSize < file.size){
 //先发送文件名称
 //websocket.send(file.name);
 //处理文件发送(字节)
 startSize = endSize;
 if(paragraph > (file.size - endSize)){
 endSize = file.size;
 }else{
 endSize += paragraph ;
 }
 if (file.webkitSlice) {
 //webkit浏览器
 blob = file.webkitSlice(startSize, endSize);
 }else
 blob = file.slice(startSize, endSize);
 reader.readAsArrayBuffer(blob);
 }
 }
}
 
//显示处理进程
function uploadProgress(uploadLen) {
 var percentComplete = Math.round(uploadLen * 100 / file.size);
 document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
 
 //保存到LocalStorage一边下次传输,可以记忆起这个断点
 localStorage.setItem(file.lastModifiedDate + "_" + file.name, uploadLen);
 
}
 
//WebSocket连接
function webSocketConn(){
 try{
 var readyState = new Array("正在连接", "已建立连接", "正在关闭连接"
 , "已关闭连接");
 var host = "ws://localhost:8000";
 websocket = new WebSocket(host);
 websocket.onopen = function(){
 msg.innerHTML += "<p>Socket状态: " + readyState[websocket.readyState] + "</p>";
 };
 websocket.onmessage = function(event){
 //每上传一个分片之后,等待介绍了服务端的提示之后再做下一个分片上传
 if(event.data.indexOf("ok") != -1 && uploadState == 1){
 if(endSize == file.size){
 localStorage.removeItem(file.lastModifiedDate + "_" + file.name);
 msg.innerHTML += "<p>上传完成!!</p>";
 websocket.close();//结束上传
 }else{
 uploadFile();
 }
 }
 };
 websocket.onclose = function(){
 msg.innerHTML += "<p>Socket状态: " + readyState[websocket.readyState] + "</p>";
 };
 msg.innerHTML += "<p>Socket状态: " + readyState[websocket.readyState] + "</p>";
 }catch(exception){
 msg.innerHTML += "<p>有错误发生</p>";
 return;
 }
}
 
/*
暂停上传
*/
function pauseUpload(){
 uploadState = 2;
}
 
/**
 * 从localStorage检查最后一次上传的字节
 */
function getLastestUploadEndSize(uploadFile){
 var lastestLen = localStorage.getItem(uploadFile.lastModifiedDate + "_" + uploadFile.name);
 if(lastestLen){
 return parseInt(lastestLen);
 }else{
 return 0;
 }
}
 
 
/*
 发送文件名
*/
function sendFileName(){
 websocket.send(file.name);
}
/**
 * 选择文件之后触发事件
 */
function fileSelected() {
 file = document.getElementById('fileToUpload').files[0];
 if (file) {
 var fileSize = 0;
 if (file.size > 1024 * 1024)
 fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
 else
 fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
 
 document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
 document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
 document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
 }
}

服务端:

package fileUpload;
 
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.security.MessageDigest;
 
 
 
public class UploadServer {
 private int port = 8000;
 private ServerSocket serverSocket;
 
 public UploadServer() throws IOException {
 serverSocket = new ServerSocket(port);
 System.out.println("服务器启动");
 }
 
 private void service() {
 Socket socket = null;
 while (true) {
 try {
 socket = serverSocket.accept();
 Thread workThread = new Thread(new Handler(socket));
 workThread.start();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 
 class Handler implements Runnable {
 private Socket socket;
 private boolean hasHandshake = false;
 Charset charset = Charset.forName("UTF-8"); 
 private File file = null;
 private FileOutputStream fileOut = null;
 
 public Handler(Socket socket) {
 this.socket = socket;
 }
 
 private PrintWriter getWriter(Socket socket) throws IOException {
 OutputStream socketOut = socket.getOutputStream();
 return new PrintWriter(socketOut, true);
 }
 
 
 public String echo(String msg) {
 return "echo:" + msg;
 }
 
 public void run() {
 
 try {
 System.out.println("New connection accepted"
 + socket.getInetAddress() + ":" + socket.getPort());
 InputStream in = socket.getInputStream();
 
 PrintWriter pw = getWriter(socket);
 //读入缓存
 byte[] buf = new byte[1024];
 //读到字节
 int len = in.read(buf, 0, 1024);
 //读到字节数组
 byte[] res = new byte[len];
 System.arraycopy(buf, 0, res, 0, len);
 String key = new String(res);
 if(!hasHandshake && key.indexOf("Key") > 0){
 key = key.substring(0, key.indexOf("==") + 2);
 key = key.substring(key.indexOf("Key") + 4, key.length()).trim();
 key+= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
 MessageDigest md = MessageDigest.getInstance("SHA-1"); 
 md.update(key.getBytes("utf-8"), 0, key.length());
 byte[] sha1Hash = md.digest(); 
 sun.misc.BASEEncoder encoder = new sun.misc.BASEEncoder(); 
 key = encoder.encode(sha1Hash); 
 pw.println("HTTP/1.1 101 Switching Protocols");
 pw.println("Upgrade: websocket");
 pw.println("Connection: Upgrade");
 pw.println("Sec-WebSocket-Accept: " + key);
 pw.println();
 pw.flush();
 hasHandshake = true;
 
 //接收数据
 byte[] first = new byte[1];
 int read = in.read(first, 0, 1);
 while(read > 0){
 int b = first[0] & 0xFF;
 //boolean fin = (b & 0x80) > 0;
 // int rsv = (b & 0x70) >>> 4;
 byte opCode = (byte) (b & 0x0F);
 
 if(opCode == 8){
 socket.getOutputStream().close();
 file = null;
 fileOut.flush();
 fileOut.close();
 fileOut = null;
 break;
 }
 b = in.read();
 int payloadLength = b & 0x7F;
 if (payloadLength == 126) {
 byte[] extended = new byte[2];
 in.read(extended, 0, 2);
 int shift = 0;
 payloadLength = 0;
 for (int i = extended.length - 1; i >= 0; i--) {
 payloadLength = payloadLength + ((extended[i] & 0xFF) << shift);
 shift += 8;
 }
 
 } else if (payloadLength == 127) {
 byte[] extended = new byte[8];
 in.read(extended, 0, 8);
 int shift = 0;
 payloadLength = 0;
 for (int i = extended.length - 1; i >= 0; i--) {
 payloadLength = payloadLength + ((extended[i] & 0xFF) << shift);
 shift += 8;
 }
 }
 
 //掩码
 byte[] mask = new byte[4];
 in.read(mask, 0, 4);
 int readThisFragment = 1;
 ByteBuffer byteBuf = ByteBuffer.allocate(payloadLength);
 while(payloadLength > 0){
 int masked = in.read();
 masked = masked ^ (mask[(int) ((readThisFragment - 1) % 4)] & 0xFF);
 byteBuf.put((byte) masked);
 payloadLength--;
 readThisFragment++;
 }
 byteBuf.flip();
 if(opCode == 1){
 getChar(byteBuf.array());
 }else
 outFile(byteBuf.array());
 in.read(first, 0, 1);
 }
 
 }
 in.close();
 } catch (Exception e) {
 e.printStackTrace();
 } finally {
 try {
 if (socket != null)
 socket.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 
 private void responseClient(boolean finalFragment) throws IOException {
 ByteBuffer byteBuf = ByteBuffer.allocate(10);
 byteBuf.put("ok".getBytes("UTF-8"));
 OutputStream out = socket.getOutputStream();
 int first = 0x00;
 //是否是
输出最后的WebSocket响应片段,默认 if (finalFragment) { first = first + 0x80; first = first + 0x1; } out.write(first); if (byteBuf.limit() < 126) { out.write(byteBuf.limit()); } else if (byteBuf.limit() < 65536) { out.write(126); out.write(byteBuf.limit() >>> 8); out.write(byteBuf.limit() & 0xFF); } else { // Will never be more than 2^31-1 out.write(127); out.write(0); out.write(0); out.write(0); out.write(0); out.write(byteBuf.limit() >>> 24); out.write(byteBuf.limit() >>> 16); out.write(byteBuf.limit() >>> 8); out.write(byteBuf.limit() & 0xFF); } // Write the content out.write(byteBuf.array(), 0, byteBuf.limit()); out.flush(); } /** * 方法说明: * @开发:linrb * @创建时间:2012-8-21 * @param array * @throws IOException */ private void getChar(byte[] array) throws IOException { ByteArrayInputStream byteIn = new ByteArrayInputStream(array); InputStreamReader reader = new InputStreamReader(byteIn, charset.newDecoder()); int b = 0; String res = ""; try { while((b = reader.read()) > 0){ res += (char)b; } } catch (IOException e) { e.printStackTrace(); } file = new File("C:/" + res); } /** * 方法说明: * @开发:linrb * @创建时间:2012-8-14 * @param array * @throws IOException */ private void outFile(byte[] array) throws IOException { if(fileOut == null){ fileOut = new FileOutputStream(file, true); } fileOut.write(array); responseClient(true); } } public static void main(String[] args) throws IOException { new UploadServer().service(); } }

下载本文
显示全文
专题