webuploader大文件 分片 断点续传
来源:互联网 发布:cad制图机械软件 编辑:程序博客网 时间:2024/05/16 17:25
原文参考于http://blog.csdn.net/chenxiaoyu_csdn/article/details/70847203其中修复了原文章中由于网络中断等问题,断点续传时会再次上传已经上传文件的问题.修复了不需要分片的文件,上传过程中会出现异常的问题.
- webupload官网下载需要的Uploader.swf、webuploader.css、webuploader.js 文件
- jsp 页面
<div id="uploadfile"> <!--用来存放文件信息--> <div id="thelist" class="uploader-list"></div> <div class="form-group form-inline"> <div id="picker">选择文件</div> <button id="ctlBtn" class="btn btn-default">开始上传</button> </div> <p style="color: red;margin-top: 80px;" id="fileError"></p> </div>
3.js 代码<script type="text/javascript"> //var projcetName =$("#project").val(); $(function(){var $list = $('#thelist'), $btn = $('#ctlBtn'); var fileMd5;//自定义参数 文件名var fileName; //监听分块上传过程中的三个时间点 WebUploader.Uploader.register({ "before-send-file":"beforeSendFile", //整个文件上传前调用 "before-send":"beforeSend", //每个分片上传前 "after-send-file":"afterSendFile", //分片上传完毕 },{ //时间点1:所有分块进行上传之前调用此函数 beforeSendFile:function(file){ console.log("beforeSendFile"); var deferred = WebUploader.Deferred(); //1、计算文件的唯一标记,用于断点续传 (new WebUploader.Uploader()).md5File(file,0,10*1024*1024) .progress(function(percentage){ $('#item1').find("p.state").text("正在读取文件信息..."); }) .then(function(val){ fileMd5=val; $('#item1').find("p.state").text("成功获取文件信息..."); //获取文件信息后进入下一步 deferred.resolve(); }); return deferred.promise(); }, //时间点2:如果有分块上传,则每个分块上传之前调用此函数 beforeSend:function(block){ console.log("beforeSend"); var deferred = WebUploader.Deferred(); $.ajax({ type:"POST", url:"checkOrMerge?action=checkChunk", data:{ //文件唯一标记 fileMd5:fileMd5, //当前分块下标 chunk:block.chunk, //当前分块大小 chunkSize:block.end-block.start }, dataType:"json", success:function(response){ if(response.ifExist){ console.log("分片存在:"+block.chunk) //分块存在,跳过 deferred.reject(); }else{ console.log("分片不存在:"+block.chunk) //分块不存在或不完整,重新发送该分块内容 deferred.resolve(); } } }); this.owner.options.formData.fileMd5 = fileMd5; console.log("继续执行") //deferred.resolve(); return deferred.promise(); }, //时间点3:所有分块上传成功后调用此函数 afterSendFile:function(file){ console.log("afterSendFile"); fileName=file.name; //为自定义参数文件名赋值 //如果分块上传成功,则通知后台合并分块 $.ajax({ type:"POST", url:"checkOrMerge?action=mergeChunks", data:{ fileMd5:fileMd5, fileName:fileName, ext:file.ext, //文件扩展名 projectName: $("#project option:selected").text() //项目名称 }, success:function(response){ var data= eval('(' + response + ')'); var filePath = data.path; console.log(filePath); //存储文件路径 var path=$("#filePath").val(); if(path!=""){ path=path+"|"+filePath; }else{ path=filePath; } $("#filePath").val(path); //alert("上传成功"); //var path = "uploads/"+fileMd5+".mp4"; //$("#item1").attr("src",path); } }); } }); var uploader = WebUploader.create({ resize: false, // 不压缩image swf: '/res/webuploader-0.1.5/uploader.swf', // swf文件路径 formData: { projectName: ""}, server: 'upload', // 文件接收服务端。 pick: '#picker', // 选择文件的按钮。可选 chunked: true, //是否要分片处理大文件上传 chunkSize:10*1024*1024, //分片上传,每片2M,默认是5M //auto: false //选择文件后是否自动上传 chunkRetry : 2, //如果某个分片由于网络问题出错,允许自动重传次数 //runtimeOrder: 'html5,flash', // 在上传当前文件时,准备好下一个文件 prepareNextFile:true, duplicate : false,//是否重复上传(同时选择多个一样的文件),true可以重复上传 accept: { title: '语音上传', extensions: 'wav,zip,rar', mimeTypes: 'audio/x-wav,.zip,.rar' } }); //当文件被加入队列之前触发 uploader.on('beforeFileQueued', function (file,data) { //项目名称,在后台作为文件夹路径 var projcetName =$("#project").val(); if(projcetName==""){ $("#projectError").text("请先选择项目名称再上传文件!"); return false; }else{ $("#projectError").text(""); } //选定项目名称后 ,不可更改 $("#project").attr("disabled","disabled"); }); // 当有文件被添加进队列的时候 uploader.on( 'fileQueued', function( file ) { $list.append( '<div id="' + file.id + '" class="item">' + '<span class="info">' + file.name + '</span>' + '<b class="state" style="width:90px;">等待上传...</b>' + '</div>' ); }); //绑定uploadBeforeSend事件来给每个独立的文件添加参数 uploader.on( 'uploadBeforeSend', function( block, data ) { //设置data参数 data.projectName= $("#project").find("option:selected").text(); // 将存在file对象中的md5数据携带发送过去。},2); // 文件上传过程中创建进度条实时显示。 uploader.on( 'uploadProgress', function( file, percentage ) { var $li = $( '#'+file.id ), $percent = $li.find('.progress .progress-bar'); // 避免重复创建 if ( !$percent.length ) { $percent = $('<div class="progress progress-striped active">' + '<div class="progress-bar" role="progressbar" style="width: 0%">' + '</div>' + '</div>').appendTo( $li ).find('.progress-bar'); }//进度条以百分比的形式显示 $li.find('b.state').text('上传中'+Math.floor(percentage * 100) + '%' ); $percent.css( 'width', percentage * 100 + '%' ); }); // 文件上传成功 uploader.on( 'uploadSuccess', function( file,ret) { //返回文件的保存路径 if(ret.flag==true){ console.log(ret.path); var path=$("#filePath").val(); if(path!=""){ path=path+"|"+ret.path; }else{ path=ret.path; } $("#filePath").val(path); } $( '#'+file.id ).find('b.state').text('上传成功'); $( '#'+file.id ).find('b.state').css("color","green"); }); // 文件上传失败,显示上传出错 uploader.on( 'uploadError', function( file,ret ) { status=false; $( '#'+file.id ).find('b.state').text('上传失败'); }); // 完成上传完 uploader.on( 'uploadComplete', function( file ) { $( '#'+file.id ).find('.progress').fadeOut(); }); $btn.on('click', function () { if ($(this).hasClass('disabled')) { return false; } uploader.upload(); // if (state === 'ready') { // uploader.upload(); // } else if (state === 'paused') { // uploader.upload(); // } else if (state === 'uploading') { // uploader.stop(); // } });}); </script>
<div id="uploadfile"> <!--用来存放文件信息--> <div id="thelist" class="uploader-list"></div> <div class="form-group form-inline"> <div id="picker">选择文件</div> <button id="ctlBtn" class="btn btn-default">开始上传</button> </div> <p style="color: red;margin-top: 80px;" id="fileError"></p> </div>3.js 代码
<script type="text/javascript"> //var projcetName =$("#project").val(); $(function(){var $list = $('#thelist'), $btn = $('#ctlBtn'); var fileMd5;//自定义参数 文件名var fileName; //监听分块上传过程中的三个时间点 WebUploader.Uploader.register({ "before-send-file":"beforeSendFile", //整个文件上传前调用 "before-send":"beforeSend", //每个分片上传前 "after-send-file":"afterSendFile", //分片上传完毕 },{ //时间点1:所有分块进行上传之前调用此函数 beforeSendFile:function(file){ console.log("beforeSendFile"); var deferred = WebUploader.Deferred(); //1、计算文件的唯一标记,用于断点续传 (new WebUploader.Uploader()).md5File(file,0,10*1024*1024) .progress(function(percentage){ $('#item1').find("p.state").text("正在读取文件信息..."); }) .then(function(val){ fileMd5=val; $('#item1').find("p.state").text("成功获取文件信息..."); //获取文件信息后进入下一步 deferred.resolve(); }); return deferred.promise(); }, //时间点2:如果有分块上传,则每个分块上传之前调用此函数 beforeSend:function(block){ console.log("beforeSend"); var deferred = WebUploader.Deferred(); $.ajax({ type:"POST", url:"checkOrMerge?action=checkChunk", data:{ //文件唯一标记 fileMd5:fileMd5, //当前分块下标 chunk:block.chunk, //当前分块大小 chunkSize:block.end-block.start }, dataType:"json", success:function(response){ if(response.ifExist){ console.log("分片存在:"+block.chunk) //分块存在,跳过 deferred.reject(); }else{ console.log("分片不存在:"+block.chunk) //分块不存在或不完整,重新发送该分块内容 deferred.resolve(); } } }); this.owner.options.formData.fileMd5 = fileMd5; console.log("继续执行") //deferred.resolve(); return deferred.promise(); }, //时间点3:所有分块上传成功后调用此函数 afterSendFile:function(file){ console.log("afterSendFile"); fileName=file.name; //为自定义参数文件名赋值 //如果分块上传成功,则通知后台合并分块 $.ajax({ type:"POST", url:"checkOrMerge?action=mergeChunks", data:{ fileMd5:fileMd5, fileName:fileName, ext:file.ext, //文件扩展名 projectName: $("#project option:selected").text() //项目名称 }, success:function(response){ var data= eval('(' + response + ')'); var filePath = data.path; console.log(filePath); //存储文件路径 var path=$("#filePath").val(); if(path!=""){ path=path+"|"+filePath; }else{ path=filePath; } $("#filePath").val(path); //alert("上传成功"); //var path = "uploads/"+fileMd5+".mp4"; //$("#item1").attr("src",path); } }); } }); var uploader = WebUploader.create({ resize: false, // 不压缩image swf: '/res/webuploader-0.1.5/uploader.swf', // swf文件路径 formData: { projectName: ""}, server: 'upload', // 文件接收服务端。 pick: '#picker', // 选择文件的按钮。可选 chunked: true, //是否要分片处理大文件上传 chunkSize:10*1024*1024, //分片上传,每片2M,默认是5M //auto: false //选择文件后是否自动上传 chunkRetry : 2, //如果某个分片由于网络问题出错,允许自动重传次数 //runtimeOrder: 'html5,flash', // 在上传当前文件时,准备好下一个文件 prepareNextFile:true, duplicate : false,//是否重复上传(同时选择多个一样的文件),true可以重复上传 accept: { title: '语音上传', extensions: 'wav,zip,rar', mimeTypes: 'audio/x-wav,.zip,.rar' } }); //当文件被加入队列之前触发 uploader.on('beforeFileQueued', function (file,data) { //项目名称,在后台作为文件夹路径 var projcetName =$("#project").val(); if(projcetName==""){ $("#projectError").text("请先选择项目名称再上传文件!"); return false; }else{ $("#projectError").text(""); } //选定项目名称后 ,不可更改 $("#project").attr("disabled","disabled"); }); // 当有文件被添加进队列的时候 uploader.on( 'fileQueued', function( file ) { $list.append( '<div id="' + file.id + '" class="item">' + '<span class="info">' + file.name + '</span>' + '<b class="state" style="width:90px;">等待上传...</b>' + '</div>' ); }); //绑定uploadBeforeSend事件来给每个独立的文件添加参数 uploader.on( 'uploadBeforeSend', function( block, data ) { //设置data参数 data.projectName= $("#project").find("option:selected").text(); // 将存在file对象中的md5数据携带发送过去。},2); // 文件上传过程中创建进度条实时显示。 uploader.on( 'uploadProgress', function( file, percentage ) { var $li = $( '#'+file.id ), $percent = $li.find('.progress .progress-bar'); // 避免重复创建 if ( !$percent.length ) { $percent = $('<div class="progress progress-striped active">' + '<div class="progress-bar" role="progressbar" style="width: 0%">' + '</div>' + '</div>').appendTo( $li ).find('.progress-bar'); }//进度条以百分比的形式显示 $li.find('b.state').text('上传中'+Math.floor(percentage * 100) + '%' ); $percent.css( 'width', percentage * 100 + '%' ); }); // 文件上传成功 uploader.on( 'uploadSuccess', function( file,ret) { //返回文件的保存路径 if(ret.flag==true){ console.log(ret.path); var path=$("#filePath").val(); if(path!=""){ path=path+"|"+ret.path; }else{ path=ret.path; } $("#filePath").val(path); } $( '#'+file.id ).find('b.state').text('上传成功'); $( '#'+file.id ).find('b.state').css("color","green"); }); // 文件上传失败,显示上传出错 uploader.on( 'uploadError', function( file,ret ) { status=false; $( '#'+file.id ).find('b.state').text('上传失败'); }); // 完成上传完 uploader.on( 'uploadComplete', function( file ) { $( '#'+file.id ).find('.progress').fadeOut(); }); $btn.on('click', function () { if ($(this).hasClass('disabled')) { return false; } uploader.upload(); // if (state === 'ready') { // uploader.upload(); // } else if (state === 'paused') { // uploader.upload(); // } else if (state === 'uploading') { // uploader.stop(); // } });}); </script>
4. 后台文件上传及合并代码
// 上传文件@RequestMapping(value = "upload")public void uploadFile(HttpServletRequest request,HttpServletResponse response, String projectName)throws IOException {response.setCharacterEncoding("UTF-8");Map map = new HashMap<>();MultipartFile uploadFile = ((MultipartHttpServletRequest) request).getFile("file");String fileMd5 = request.getParameter("fileMd5");String chunk = request.getParameter("chunk");String path = audioPath;File file = new File(path + fileMd5);if (!file.exists()) {file.mkdirs();// 创建文件夹}// 保存文件File chunkFile = new File(path + fileMd5 + "/" + chunk);if (!chunkFile.exists()) {chunkFile.createNewFile();}uploadFile.transferTo(chunkFile);}// 合并或验证分片文件是否需要上传@RequestMapping(value = "checkOrMerge")public void checkOrMerge(HttpServletRequest request,HttpServletResponse response) throws IOException {response.setCharacterEncoding("UTF-8");String savePath = audioPath;String action = request.getParameter("action");if (action.equals("mergeChunks")) {// 合并文件// 需要合并的文件的目录标记// 文件MD5String fileMd5 = request.getParameter("fileMd5");// 文件名称String fileName = request.getParameter("fileName");// 文件扩展名String suffixName = request.getParameter("ext");// 项目名称String projectName = request.getParameter("projectName");System.out.println("fileMd5 :" + fileMd5);System.out.println("fileName :" + fileName);System.out.println("projectName :" + projectName);// 读取目录里的所有文件File f = new File(savePath + fileMd5);File[] fileArray = f.listFiles(new FileFilter() {// 排除目录只要文件@Overridepublic boolean accept(File pathname) {if (pathname.isDirectory()) {return false;}return true;}});System.out.println(" fileArray " + fileArray);// 转成集合,便于排序List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));// 需要合并的文件才进行排序,即分片的大小大于1if (fileList != null && fileList.size() > 1) {Collections.sort(fileList, new Comparator<File>() {@Overridepublic int compare(File o1, File o2) {// TODO Auto-generated method stubif (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {return -1;}return 1;}});}// 合并的文件夹File mergeFile = new File(savePath + projectName);if (!mergeFile.exists()) {mergeFile.mkdirs();}// UUID.randomUUID().toString()-->随机名File outputFile = new File(savePath + projectName + "/" + fileName);// 创建文件outputFile.createNewFile();// 输出流FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();// 合并FileChannel inChannel;for (File file : fileList) {inChannel = new FileInputStream(file).getChannel();inChannel.transferTo(0, inChannel.size(), outChnnel);inChannel.close();// 删除分片file.delete();}outChnnel.close();// 清除文件夹File tempFile = new File(savePath + fileMd5);if (tempFile.isDirectory() && tempFile.exists()) {tempFile.delete();}System.out.println("合并成功");Map<String, String> map = new HashMap<>();// 文件路径map.put("path", projectName + "/" + fileName);response.getWriter().print(JSON.toJSON(map));} else if (action.equals("checkChunk")) {// 检查当前分块是否上传成功String fileMd5 = request.getParameter("fileMd5");String chunk = request.getParameter("chunk");String chunkSize = request.getParameter("chunkSize");File checkFile = new File(savePath + fileMd5 + "/" + chunk);response.setContentType("text/html;charset=utf-8");// 检查文件是否存在,且大小是否一致if (checkFile.exists()&& checkFile.length() == Integer.parseInt(chunkSize)) {// 上传过response.getWriter().write("{\"ifExist\":1}");} else {// 没有上传过response.getWriter().write("{\"ifExist\":0}");}}}
阅读全文
1 0
- webuploader大文件 分片 断点续传
- webuploader分片上传大文件
- webUploader大文件断点续传学习心得
- webuploader 实现大文件 分片上传
- iOS大文件分片上传和断点续传
- 基于Struts2大文件分片断点续传
- 大文件分片上传和断点续传
- iOS大文件分片上传和断点续传
- webuploader 实现文件断点续传
- 前段WebUploader;JavaEE大文件分片上传接收
- 百度Webuploader 大文件分片上传(.net接收)
- java使用WebUploader做大文件的分块和断点续传
- java使用WebUploader做大文件的分块和断点续传
- 大文件的分片传,断点续传,md5校验
- 基于NodeJs的Express及Webuploader实现大文件分片上传与合并(一)
- webuploader在springMVC+jquery+Java开发环境下的大文件分片上传
- 基于NodeJs的Express及Webuploader实现大文件分片上传与合并(二)——组件化实现
- 使用webuploader上传大文件
- CAD转PDF彩色怎么转
- SQLite表导出csv文件
- python读取外部数据之excel数据获取及参数说明
- 使用森林优化算法的特征选择
- Android 基于Message的进程间通信 Messenger完全解析
- webuploader大文件 分片 断点续传
- 01迷宫
- java之Apache POI 合并单元格
- table access by index rowid
- python的正则使用
- openssh-server
- Android中.9图片的含义及制作教程
- 【Hash】BZOJ4337(BJOI2015)[树的同构]题解
- PMP认证申请流程