使用WebUploader實現(xiàn)分片斷點上傳文件功能(二)
寫在前面:
這幾天,有去研究一下WebUploader上傳文件,前面的博客有記錄下使用WebUploader簡單上傳文件的例子,今天就把分片斷點上傳的例子也記錄下吧,在博客園中,也查看了一些資料,基本上后臺處理數(shù)據(jù)都是用的Servlet,或者是SpringMVC,由于最近的項目一直都是Struts2,所以這里就用Struts2中的action來對數(shù)據(jù)進行處理,達到分片上傳文件的效果。
1.什么是分片上傳?
顧名思義,就是把文件分成一片片,即讓一個文件,分割成好幾個小文件,然后再上傳。這樣做的好處是便于上傳大文件。
2.分片上傳大致思路:
1.前臺頁面,選擇文件,點擊按鈕進行上傳。
2.WebUploader將上傳的文件,分割成指定的個數(shù),挨個發(fā)送到服務端后臺。
3.服務器接收分割后的小文件,并存儲到臨時文件夾下
4.服務器接收分割后的小文件完畢后,前臺頁面執(zhí)行上傳成功函數(shù)。
5.在上傳成功函數(shù)中,發(fā)送請求到服務器,請求合并小文件為一個整體的文件。
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();
//網(wǎng)站的訪問跟路徑
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的創(chuàng)建,最好等dom元素也就是下面的div創(chuàng)建好之后再創(chuàng)建,因為里面有用到選擇文件按鈕,
不然會創(chuàng)建報錯,這是很容易忽視的地方,故這里放到$(function(){}來進行創(chuàng)建*/
var uploader = WebUploader.create({
// swf文件路徑
swf: '${baseURL}/webuploader0.1.5/Uploader.swf',
// 文件接收服務端地址。
server: '${baseURL}/uploadFile2',
// [默認值:'file'] 設置文件上傳域的name。
fileVal:'upload',
// 選擇文件的按鈕??蛇x。
// 內部根據(jù)當前運行是創(chuàng)建,可能是input元素,也可能是flash.
pick:
{
multiple: false,
id: '#filePicker'
},
// 上傳并發(fā)數(shù)。允許同時最大上傳進程數(shù)[默認值:3] 即上傳文件數(shù)
/*這個是關鍵 如果開啟了分片上傳 并不限制同時上傳的數(shù)目 會導致后臺接受的分片錯亂 比如按正常的分片第一片應該是開頭
但接收的可能就變成第三片從而順序錯亂 這是由于百度webuploader默認允許同時最大上傳進程數(shù)為3個
所以會導致接受順序錯亂從而重組發(fā)生錯誤,故這里設置為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("");
//具體邏輯根據(jù)項目需求來寫 這里知識簡單的舉個例子寫下
$one = $("<div id='"+file.id+"'>"+file.name+"</div>");
$two = $("<div id='state'>等待上傳......</div>");
$("#fileList").append($one);
$("#fileList").append($two);
});
// 文件上傳過程中創(chuàng)建進度條實時顯示。
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",
//發(fā)送到后臺的參數(shù)
{
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) {
// 具體邏輯...
});
//點擊上傳按鈕觸發(fā)事件
$("#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 {
/*用于接收分割請求的每個小文件的相關參數(shù)*/
//記得提供對應的get set方法
//上傳文件對象(和表單type=file的name值一致)
private File upload;
//文件名
private String uploadFileName;
//上傳類型
private String uploadContentType;
/**
* 以下變量都是public,參數(shù)太多,不想設為private再去寫get,set方法了,
* 就偷個懶直接用了public了
*/
//文件分片序號
public String chunk;
public String guid;//合并與分割都有用到
//用于接收發(fā)送合并請求的相關參數(shù)
public String fileName; //文件名
public String chunks; //分割數(shù)量
//當進行分片上傳文件的時候,每上傳一個小文件就會調用這個方法,這個就跟普通的保存文件沒啥區(qū)別的
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/" ;
//創(chuàng)建 合并文件夾
new File(path).mkdir();
//創(chuàng)建 合并后的文件
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>
好啦,到這里,一個簡單的文件分片斷點上傳就完成了。
對了補充說明下,后臺只是接收了一些簡單的參數(shù)而已,而從前臺WebUploader傳遞過來的參數(shù)當然不止上面那幾個了,所以,可以學會用F12調試模式,進行查看發(fā)送的請求,以及相關的請求參數(shù),這里就不多說了
運行截圖:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- 關于webuploader插件使用過程遇到的小問題
- 推薦三款不錯的圖片壓縮上傳插件(webuploader、localResizeIMG4、LUploader)
- 百度多文件異步上傳控件webuploader基本用法解析
- 使用WebUploader實現(xiàn)上傳文件功能(一)
- 快速掌握jQuery插件WebUploader文件上傳
- webuploader 實現(xiàn)圖片批量上傳功能附實例代碼
- webuploader實現(xiàn)上傳圖片到服務器功能
- webuploader模態(tài)框ueditor顯示問題解決方法
- webuploader分片上傳的實現(xiàn)代碼(前后端分離)
- php + WebUploader實現(xiàn)圖片批量上傳功能
相關文章
Java設計模式之策略模式_動力節(jié)點Java學院整理
策略模式是對算法的封裝,把一系列的算法分別封裝到對應的類中,并且這些類實現(xiàn)相同的接口,相互之間可以替換。接下來通過本文給大家分享Java設計模式之策略模式,感興趣的朋友一起看看吧2017-08-08
Java filter中的chain.doFilter使用詳解
這篇文章主要介紹了Java filter中的chain.doFilter使用詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
Maven發(fā)布封裝到中央倉庫時候報錯:no default secret key
這篇文章主要介紹了Maven發(fā)布封裝到中央倉庫時候報錯:no default secret key,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12

