写在前面:

  这几天,有去研究一下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="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分片断点上传文件(二)的更多相关文章

  1. java实现视频断点上传文件

    一.概述 所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载.在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了.一般断点下载时才用到Range和Content- ...

  2. iOS 断点上传文件

    项目开发中,有时候我们需要将本地的文件上传到服务器,简单的几张图片还好,但是针对iPhone里面的视频文件进行上传,为了用户体验,我们有必要实现断点上传.其实也不是真的断点,这里我们只是模仿断点机制. ...

  3. WebUploader点击上传文件选择框会延迟几秒才会显示

    accept: { title: 'Images', extensions: 'jpg,jpeg,png', mimeTypes: 'image/*' } 改为 accept: { title: 'I ...

  4. WebUploader上传文件(一)

    写在前面: 文件上传方式很多的,对于大文件的上传,在本次项目中也有涉及,主要是用了分片断点上传大文件.所以就去了解了一下WebUploader,先从简单的上传文件开始吧~ 在代码中写注释,这样看的比较 ...

  5. Thinkphp拖拽上传文件-使用webuploader插件(自己改动了一些地方)——分片上传

    html页面: <!DOCTYPE html> <html class="js cssanimations"> <head> <meta  ...

  6. webuploader 上传文件 生成链接下载文件

    最近 在asp.net MVC 项目 需要实现一个Excel和 图片上传功能.之前有使用过SWFUpload 做过上传图片功能,在本次实现过程中,有人推荐WebUploader 上传组件,因此采用we ...

  7. JQ 上传文件(单个,多个,分片)

    最原始的方式: 前端代码: <div> <span>最原始的方式</span><br /> <span>条件1:必须是 post 方式< ...

  8. 文件断点上传,html5实现前端,java实现服务器

    断点上传能够防止意外情况导致上传一半的文件下次上传时还要从头下载,网上有很多关于断点的实现,这篇文章只是从前到后完整的记录下一个可用的实例,由于生产环境要求不高,而且就是提供给一两个人用,所以我简化了 ...

  9. WebUploader 上传插件结合bootstrap的模态框使用时选择上传文件按钮无效问题的解决方法

    由于种种原因(工作忙,要锻炼健身,要看书,要学习其他兴趣爱好,谈恋爱等),博客已经好久没有更新,为这个内心一直感觉很愧疚,今天开始决定继续更新博客,每周至少一篇,最多不限篇幅. 今天说一下,下午在工作 ...

随机推荐

  1. Shell 快速指南

    Shell 快速指南 ███████╗██╗ ██╗███████╗██╗ ██╗ ██╔════╝██║ ██║██╔════╝██║ ██║ ███████╗███████║█████╗ ██║ ...

  2. 自动化之路 python psutil模块 收集硬件信息

    一.psutil模块 1. psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控,分析和限制系统资源及进程的管理.它实现了 ...

  3. jquery.base64.js 中文乱码处理

    c# 转码:Convert.ToBase64String(Encoding.UTF8.GetBytes(str)) js 解码:$.base64.atob(this.options.valids, t ...

  4. [react] 细数 React 的原罪

    Props & onChange 的原罪 .「props & onChange 接口规范」它不是一个典型的「程序接口规范」. 当你拿到一个可视组件的 ref,却没有类似 setProp ...

  5. Spring-MVC理解之一:应用上下文webApplicationContext

    一.先说ServletContext javaee标准规定了,servlet容器需要在应用项目启动时,给应用项目初始化一个ServletContext作为公共环境容器存放公共信息.ServletCon ...

  6. 【java提高】---HashMap解析(一)

    HashMap解析(一) 平时一直再用hashmap并没有稍微深入的去了解它,自己花点时间想往里面在深入一点,发现它比arraylist难理解很多,好多东西目前还不太能理解等以后自己知识更加丰富在过来 ...

  7. 三十天学不会TCP,UDP/IP编程--MAC地址和数据链路层

    这篇文章主要是来做(da)推(guang)介(gao)的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会 ...

  8. 日志模块---logging

    作用 在程序的运行过程中,会遇到很多需要打印的中间信息,通过使用logging模块可以详细的输出信息,不同于print()函数的单一功能. 应用场景 对于软件程序的运行过程中输出中间信息,如账单信息, ...

  9. 用tortoiseGit管理GitHub项目代码(完整教程)

    一.为什么要写这篇博客呢,因为在一开始用tortoiseGit来管理项目的时候,在百度上找了很多教程,但是感觉说的都不是很全,有些东西以及操作没写清楚,所以想写一片比较完整用tortoiseGit管理 ...

  10. 【POJ3254】Corn Fields

    http://poj.org/problem?id=3254 题意:给你一块n*m(0<n,m<=12)的地图,其中有的方格是肥沃的(用1表示),有的方格是贫瘠的(用0表示).现在约翰要在 ...