• 技术文章 >web前端 >H5教程

    HTML5断点续上传的示例代码分享

    黄舟黄舟2017-03-25 16:07:06原创922
    断点上传,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>
        &nbsp;<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.BASE64Encoder encoder = new sun.misc.BASE64Encoder();  
                        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();
        }
    }

    以上就是HTML5断点续上传的示例代码分享的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:HTML5文件操作API的代码案例详解 下一篇:HTML5之Javascript多线程的详解
    PHP编程就业班

    相关文章推荐

    • html5离线存储有哪些• 深入解析asp.net中mvc4自定义404页面(分享)• h5新增标签audio与video的使用• 你值得了解的HTTP缓存机制(代码详解)• 使用HTML5 SVG绘制各种雪花图案

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网