首页 > 开发 > Java > 正文

使用WebUploader实现分片断点上传文件功能(二)

2024-07-13 10:17:23
字体:
来源:转载
供稿:网友

写在前面:

  这几天,有去研究一下WebUploader上传文件,前面的博客有记录下使用WebUploader简单上传文件的例子,今天就把分片断点上传的例子也记录下吧,在博客园中,也查看了一些资料,基本上后台处理数据都是用的Servlet,或者是SpringMVC,由于最近的项目一直都是Struts2,所以这里就用Struts2中的action来对数据进行处理,达到分片上传文件的效果。

1.什么是分片上传?

  顾名思义,就是把文件分成一片片,即让一个文件,分割成好几个小文件,然后再上传。这样做的好处是便于上传大文件。

2.分片上传大致思路:

  1.前台页面,选择文件,点击按钮进行上传。

  2.WebUploader将上传的文件,分割成指定的个数,挨个发送到服务端后台。

  3.服务器接收分割后的小文件,并存储到临时文件夹下

  4.服务器接收分割后的小文件完毕后,前台页面执行上传成功函数。

  5.在上传成功函数中,发送请求到服务器,请求合并小文件为一个整体的文件。

  6.服务器后台对文件进行合并操作,合并完成后删除存储小文件的临时文件。 

了解了分片上传的大致过程,下面直接上demo吧。

前台页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%  String scheme = request.getScheme();  String serverName = request.getServerName();  String contextPath = request.getContextPath();  int port = request.getServerPort();  //网站的访问跟路径  String baseURL = scheme + "://" + serverName + ":" + port      + contextPath;  request.setAttribute("baseURL", baseURL);%><html><head>  <title>WebUploader文件分片上传简单示例</title>  <%--引入css样式--%>  <link href="${baseURL}/webuploader0.1.5/webuploader.css" rel="external nofollow" rel="stylesheet" type="text/css"/>  <script src="${baseURL}/ligerui2/jquery/jquery-1.9.0.min.js" type="text/javascript"></script>  <%--引入文件上传插件--%>  <script type="text/javascript" src="${baseURL}/webuploader0.1.5/webuploader.min.js"></script>  <script type="text/javascript">      $(function(){        /*        对于uploader的创建,最好等dom元素也就是下面的div创建好之后再创建,因为里面有用到选择文件按钮,        不然会创建报错,这是很容易忽视的地方,故这里放到$(function(){}来进行创建*/        var uploader = WebUploader.create({          // swf文件路径          swf: '${baseURL}/webuploader0.1.5/Uploader.swf',          // 文件接收服务端地址。          server: '${baseURL}/uploadFile2',          // [默认值:'file'] 设置文件上传域的name。          fileVal:'upload',          // 选择文件的按钮。可选。          // 内部根据当前运行是创建,可能是input元素,也可能是flash.          pick:            {              multiple: false,              id: '#filePicker'            },          // 上传并发数。允许同时最大上传进程数[默认值:3]  即上传文件数          /*这个是关键 如果开启了分片上传 并不限制同时上传的数目 会导致后台接受的分片错乱 比如按正常的分片第一片应该是开头          但接收的可能就变成第三片从而顺序错乱 这是由于百度webuploader默认允许同时最大上传进程数为3个          所以会导致接受顺序错乱从而重组发生错误,故这里设置为1*/          threads: 1,          // 自动上传修改为手动上传          auto: false,          //是否要分片处理大文件上传。          chunked: true,          // 如果要分片,分多大一片? 默认大小为5M.          chunkSize: 5 * 1024 * 1024,          // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!          resize: false,          formData: {            guid: Math.random() //这里主要用于命名存储小文件的临时文件夹              }        });        //当有文件添加进来的时候        uploader.on('fileQueued', function (file) {          //重新选择文件 进行清空          $("#fileList").html("");          //具体逻辑根据项目需求来写 这里知识简单的举个例子写下          $one = $("<div id='"+file.id+"'>"+file.name+"</div>");          $two = $("<div id='state'>等待上传......</div>");          $("#fileList").append($one);          $("#fileList").append($two);          });        // 文件上传过程中创建进度条实时显示。        uploader.on('uploadProgress', function (file, percentage) {          // 具体逻辑...          console.log("uploadProgress===="+percentage);          $("#state").text("正在上传中...");        });        // 文件上传成功处理。        uploader.on('uploadSuccess', function (file, response) {          // 具体逻辑...          console.log('upload success.../n');          console.log(uploader.options.formData.guid);          console.log(file.name);          //合并文件          $.post(            "${baseURL}/mergeFile",            //发送到后台的参数            {              guid: uploader.options.formData.guid,              chunks: Math.ceil(file.size / (5 * 1024 * 1024)),              fileName: file.name            },            function(data){            });          $("#state").text("文件上传成功啦~~~");        });        // 文件上传失败处理。        uploader.on('uploadError', function (file) {          // 具体逻辑...        });        // 上传传完毕,不管成功失败都会调用该事件,主要用于关闭进度条        uploader.on('uploadComplete', function (file) {          // 具体逻辑...        });        //点击上传按钮触发事件        $("#btnClick").click(function(){          uploader.upload();        });        //取消上传        $("#btnCancel").click(function(){          //逻辑处理..        });      });  </script></head><body style="padding:10px"><div id="layout1">  <div id="uploader-demo">    <div id="fileList" ></div>    <div id="filePicker" >选择文件</div>    <button id="btnClick">开始上传</button>    <button id="btnCancel">取消上传</button>  </div></div></body></html>

后台action:

/** * Description:com.ims.action * Author: Eleven * Date: 2017/12/26 10:50 */@Controller("FileAction")public class FileAction {  /*用于接收分割请求的每个小文件的相关参数*/  //记得提供对应的get set方法  //上传文件对象(和表单type=file的name值一致)  private File upload;  //文件名  private String uploadFileName;  //上传类型  private String uploadContentType;  /**   * 以下变量都是public,参数太多,不想设为private再去写get,set方法了,   * 就偷个懒直接用了public了   */  //文件分片序号  public String chunk;  public String guid;//合并与分割都有用到  //用于接收发送合并请求的相关参数  public String fileName; //文件名  public String chunks; //分割数量  //当进行分片上传文件的时候,每上传一个小文件就会调用这个方法,这个就跟普通的保存文件没啥区别的  public void uploadFile2() throws Exception{    String str = "D:/upload44/divide/"; //文件保存路径    //保存每个小文件的路径    String realPath = str + guid +"/" + chunk;    File tmp =new File(realPath);    FileUtils.copyFile(upload, tmp);    System.out.println("上传文件"+uploadFileName+",第几块:"+chunk+",大小:"+(upload.length()/1024/1024)+"M");  }  //文件合并  public void mergeFile() throws Exception{    String path = "D:/upload44/merge/" ;    //创建 合并文件夹    new File(path).mkdir();    //创建 合并后的文件    File newFile = new File(path + fileName);    if(!newFile.exists()){      newFile.createNewFile();    }    FileOutputStream outputStream = new FileOutputStream(newFile, true);//文件追加写入    byte[] byt = new byte[10 * 1024 * 1024];    int len;    FileInputStream temp = null;//分片文件    for (int i = 0; i < Integer.parseInt(chunks); i++) {      //"D:/upload44/divide/" + guid + "/" + i 为保存分割后的小文件的路径      temp = new FileInputStream(new File("D:/upload44/divide/" + guid + "/" + i));      while ((len = temp.read(byt)) != -1) {        System.out.println(len);        outputStream.write(byt, 0, len);      }      temp.close();    }     //当所有追加写入都写完 才可以关闭流    outputStream.close();    //删除分片文件    String path2 = "D:/upload44/divide/" + guid;    FileUtils.deleteDirectory(new File(path2));//删除目录下所有的内容    System.out.println("success!guid=" + guid + ";chunks=" + chunks + ";fileName=" + fileName);  }    public File getUpload() {    return upload;  }  public void setUpload(File upload) {    this.upload = upload;  }  public String getUploadFileName() {    return uploadFileName;  }  public void setUploadFileName(String uploadFileName) {    this.uploadFileName = uploadFileName;  }  public String getUploadContentType() {    return uploadContentType;  }  public void setUploadContentType(String uploadContentType) {    this.uploadContentType = uploadContentType;  }}

struts.xml配置:

<action name="uploadFile2" class="FileAction" method="uploadFile2"></action><action name="mergeFile" class="FileAction" method="mergeFile"></action>

好啦,到这里,一个简单的文件分片断点上传就完成了。

对了补充说明下,后台只是接收了一些简单的参数而已,而从前台WebUploader传递过来的参数当然不止上面那几个了,所以,可以学会用F12调试模式,进行查看发送的请求,以及相关的请求参数,这里就不多说了

运行截图:

WebUploader,分片,断点上传文件,WebUploader分片断点上传,WebUploader断点上传

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表