zoukankan      html  css  js  c++  java
  • java实现文件的断点续传

    java实现文件的断点续传:

    依赖:

    <!--文件上传-->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.2.1</version>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>1.4</version>
            </dependency>

    前端实现:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文件上传</title>
        <script type="text/javascript" src="js/jquery-1.8.3.min.js" ></script>
    </head>
    <body>
    <div class="row">
        <label for="fileToUpload">请选择需要上传的文件</label>
        <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();" multiple/>
    </div>
    
    <div class="row">
        <button onclick="uploadFiles()">上传</button>
        <button onclick="pauseUpload()">暂停</button>
        &nbsp;<label id="progressNumber"></label>
    </div>
    <div id="fileFrame"></div>
    <div id="msg" style="max-height: 400px; overflow:auto;min-height: 100px;">
    </div>
    <br>
    <div><h6>支持批量,支持断点续传</h6></div>
    </body>
    
    <script>
        var msg = null;
        var paragraph = 1024*1024*2;  //每次分片传输文件的大小 2M
        var blob = null;//  分片数据的载体Blob对象
        var fileList = null; //传输的文件
        var uploadState = 0;  // 0: 无上传/取消, 1: 上传中, 2: 暂停
    
        //初始化消息框
        function init(){
            msg = document.getElementById("msg");
        }
        function uploadFiles(){
            //将上传状态设置成1
            uploadState = 1;
            if(fileList.files.length>0){
                for(var i = 0; i< fileList.files.length; i++){
                    var file = fileList.files[i];
                    uploadFileInit(file,i);
                }
            }else{
                msg.innerHTML = "请选择上传文件!";
            }
        }
        /**
         * 获取服务器文件大小,开始续传
         * @param file
         * @param i
         */
        function uploadFileInit(file,i){
            if(file){
                var startSize = 0;
                var endSize = 0;
                var date = file.lastModifiedDate;
                var lastModifyTime = date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate()+"-"
                    +date.getHours()+"-"+date.getMinutes()+"-"+date.getSeconds()
                //获取当前文件已经上传大小
                jQuery.post("http://localhost:8084/crm/file/getChunkedFileSize",
                    {"fileName":encodeURIComponent(file.name),"fileSize":file.size,"lastModifyTime":lastModifyTime,"chunkedFileSize":"chunkedFileSize"},
                    function(data){
                        if(data != -1){
                            endSize = Number(data);
                        }
                        uploadFile(file,startSize,endSize,i);
    
                    });
    
            }
        }
        /**
         * 分片上传文件
         */
        function uploadFile(file,startSize,endSize,i) {
            var date = file.lastModifiedDate;
            var lastModifyTime = date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate()+"-"
                +date.getHours()+"-"+date.getMinutes()+"-"+date.getSeconds()
            var reader = new FileReader();
            reader.onload = function loaded(evt) {
                // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
                var xhr = new XMLHttpRequest();
                xhr.sendAsBinary = function(text){
                    var data = new ArrayBuffer(text.length);
                    var ui8a = new Uint8Array(data, 0);
                    for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
                    this.send(ui8a);
                }
    
                xhr.onreadystatechange = function(){
                    if(xhr.readyState==4){
                        //表示服务器的相应代码是200;正确返回了数据
                        if(xhr.status==200){
                            //纯文本数据的接受方法
                            var message=xhr.responseText;
                            message = Number(message);
                            uploadProgress(file,startSize,message,i);
                        } else{
                            msg.innerHTML = "上传出错,服务器相应错误!";
                        }
                    }
                };//创建回调方法
                xhr.open("POST",
                    "http://localhost:8084/crm/file/appendUpload2Server/"+"?"+"fileName="+encodeURIComponent(file.name)+"&fileSize="+file.size+"&lastModifyTime="+lastModifyTime
                    ,false);
                xhr.overrideMimeType("application/octet-stream;charset=utf-8");
                xhr.sendAsBinary(evt.target.result);
            };
            if(endSize < file.size){
                //处理文件发送(字节)
                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.readAsBinaryString(blob);
            }else{
                document.getElementById('progressNumber'+i).innerHTML = '100%';
            }
        }
    
        //显示处理进程
        function uploadProgress(file,startSize,uploadLen,i) {
            var percentComplete = Math.round(uploadLen * 100 / file.size);
            document.getElementById('progressNumber'+i).innerHTML = percentComplete.toString() + '%';
            //续传
            if(uploadState == 1){
                uploadFile(file,startSize,uploadLen,i);
            }
        }
    
        /*
        暂停上传
        */
        function pauseUpload(){
            uploadState = 2;
        }
    
        /**
         * 选择文件之后触发事件
         */
        function fileSelected() {
            fileList = document.getElementById('fileToUpload');
            var length = fileList.files.length;
            var frame = document.getElementById('fileFrame');
            for(var i=0; i<length; i++){
                file = fileList.files[i];
                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';
                    var nameDiv = document.createElement("div");
                    nameDiv.setAttribute("id","fileName"+i);
                    nameDiv.innerHTML='Name: ' + file.name;
                    var sizeDiv = document.createElement("div");
                    sizeDiv.setAttribute("id","fileSize"+i);
                    sizeDiv.innerHTML='fileSize: ' + fileSize;
                    var typeDiv = document.createElement("div");
                    typeDiv.setAttribute("id","progressNumber"+i);
                    typeDiv.innerHTML='';
                }
                frame.appendChild(nameDiv);
                frame.appendChild(sizeDiv);
                frame.appendChild(typeDiv);
            }
        }
    </script>
    </html>
    View Code

    java后端工具类:

    package com.zhl.push.utils;
    
    
    import org.omg.IOP.Encoding;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.io.RandomAccessFile;
    
    /**
     * @Author
     * @ClassName ImgDdUploadUtil
     * @Description TODO
     * @Date 2018/11/9 15:46
     * @Version 1.0
     */
    public class ImgDdUploadUtil {
        /**
         * 获取已上传的文件大小
         *
         * @param request
         * @param
         */
        public static Long getChunkedFileSize(HttpServletRequest request) {
            //存储文件的路径,根据自己实际确定
            String currentFilePath = "E:\front\fileUpload\tinyImgUpload-master\20181109\";
    //        PrintWriter print = null;
            try {
                request.setCharacterEncoding("utf-8");
    //            print = response.getWriter();
                String fileName = new String(request.getParameter("fileName").getBytes("ISO-8859-1"), "UTF-8");
                String lastModifyTime = request.getParameter("lastModifyTime");
                File file = new File(currentFilePath + fileName + "." + lastModifyTime);
                if (file.exists()) {
                    return file.length();
                } else {
                    return -1L;
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * 断点文件上传 1.先判断断点文件是否存在 2.存在直接流上传 3.不存在直接新创建一个文件 4.上传完成以后设置文件名称
         */
        public static Long appendUpload2Server(HttpServletRequest request) {
            try {
                request.setCharacterEncoding("utf-8");
                String fileSize = request.getParameter("fileSize");
    //            long totalSize = StringUtil.toLong(fileSize);
                Long totalSize = 0L;
                if (fileSize != null && !fileSize.equals("")) {
                    totalSize = Long.valueOf(fileSize);
                }
                RandomAccessFile randomAccessfile = null;
                long currentFileLength = 0;// 记录当前文件大小,用于判断文件是否上传完成
                String currentFilePath = "E:\front\fileUpload\tinyImgUpload-master\20181109";// 记录当前文件的绝对路径
    
                String fileName = new String(request.getParameter("fileName").getBytes("UTF-8"), "UTF-8");
                String lastModifyTime = request.getParameter("lastModifyTime");
    
                String filela = fileName.substring(fileName.lastIndexOf("."), fileName.length());//文件后缀
                String filef = fileName.substring(0, fileName.lastIndexOf("."));//文件前缀
    
    //            File file = new File(currentFilePath+fileName+"."+lastModifyTime);
    
                File file = new File(currentFilePath+"/" + filef +"_"+ lastModifyTime + filela);
                // 存在文件
                if (file.exists()) {
                    randomAccessfile = new RandomAccessFile(file, "rw");
                } else {
                    // 不存在文件,根据文件标识创建文件
                    randomAccessfile = new RandomAccessFile(currentFilePath+"/" + filef +"_"+ lastModifyTime + filela, "rw");
                }
                // 开始文件传输
                InputStream in = request.getInputStream();
                randomAccessfile.seek(randomAccessfile.length());
                byte b[] = new byte[1024];
                int n;
                while ((n = in.read(b)) != -1) {
                    Thread.sleep(1000);
                    randomAccessfile.write(b, 0, n);
                }
    
                currentFileLength = randomAccessfile.length();
    
                // 关闭文件
                closeRandomAccessFile(randomAccessfile);
                randomAccessfile = null;
                // 整个文件上传完成,修改文件后缀
    //            if (currentFileLength == totalSize) {
    //                File oldFile = new File(currentFilePath + fileName + "." + lastModifyTime);
    //                File newFile = new File(currentFilePath + fileName);
    //                if (!oldFile.exists()) {
    //                    return -1L;//重命名文件不存在
    //                }
    //                if (newFile.exists()) {// 如果存在形如test.txt的文件,则新的文件存储为test+当前时间戳.txt, 没处理不带扩展名的文件
    //                    String newName = fileName.substring(0, fileName.lastIndexOf("."))
    //                            + System.currentTimeMillis() + "."
    //                            + fileName.substring(fileName.lastIndexOf(".") + 1);
    //                    newFile = new File(currentFilePath + newName);
    //                }
    //                if (!oldFile.renameTo(newFile)) {
    //                    oldFile.delete();
    //                }
    //
    //            }
                return currentFileLength;
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 关闭随机访问文件
         *
         * @param
         */
        public static void closeRandomAccessFile(RandomAccessFile rfile) {
            if (null != rfile) {
                try {
                    rfile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    Controller 层:

    @RestController
    @RequestMapping("/file")
    public class FileUpload {
    
        @RequestMapping("/getChunkedFileSize")
        //requestParam要写才知道是前台的那个数组
        public Long getChunkedFileSize(HttpServletRequest request){
            Long chunkedFileSize = ImgDdUploadUtil.getChunkedFileSize(request);
            return chunkedFileSize;
        }
    
        @RequestMapping("/appendUpload2Server")
        //requestParam要写才知道是前台的那个数组
        public Long appendUpload2Server(HttpServletRequest request){
            Long aLong = ImgDdUploadUtil.appendUpload2Server(request);
            return aLong;
        }
    }
  • 相关阅读:
    Google Map API使用详解(三)——Google Map基本常识(上)
    Google Map API使用详解(十)——使用JavaScript创建地图详解(上)
    sethc.exe
    taobao_java
    "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) 已经在 LIBCMTD.lib(delete2.obj) 中定义 错误
    some Content
    变参 C++ 转帖
    阅读大型程序你得到什么
    一些模块
    a common jsp
  • 原文地址:https://www.cnblogs.com/dw3306/p/9936853.html
Copyright © 2011-2022 走看看