使用WebUploader实现分片断点上传文件功能(二)
程序员文章站
2023-12-10 18:45:10
写在前面:
这几天,有去研究一下webuploader上传文件,前面的博客有记录下使用webuploader简单上传文件的例子,今天就把分片断点上传的例子也记录下吧,...
写在前面:
这几天,有去研究一下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调试模式,进行查看发送的请求,以及相关的请求参数,这里就不多说了
运行截图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。