使用webuploader上傳大檔案
阿新 • • 發佈:2019-01-05
遇到一個需求,使用者想上傳超過1、2G的視訊檔案。
根據這個需求做了一些上傳速度對比,ftp上傳1G多點的檔案用時三分鐘左右
1.使用ftp上傳
(1) 建立ftp服務站點在伺服器上依次選擇控制面板——管理工具——計算機管理——Internet 資訊服務(IIS)——FTP站點——建立站點 (埠設定要避開預設埠設定其他的)
(2) 在使用者組建立一個專案相關使用者,設定使用者名稱和密碼
(設定密碼永不過期) (3 ) 在ftp站點許可權設定
(4) 實現ftp上傳 <1> 將如上配置儲存在ftp.properties中方便程式碼呼叫. <2> 上傳
/** * 上傳檔案 * * @param hostname * FTP伺服器地址 * @param port * FTP伺服器埠號 * @param username * FTP登入帳號 * @param password * FTP登入密碼 * @param pathname * FTP伺服器儲存目錄 * @param fileName * 上傳到FTP伺服器後的檔名稱 * @param inputStream * 輸入檔案流 * @return */ public static boolean uploadFile(String hostname, int port, String username, String password, String pathname, String fileName, InputStream inputStream) { boolean flag = false; long startTime=System.currentTimeMillis(); FTPClient ftpClient = new FTPClient(); ftpClient.setControlEncoding("UTF-8"); try { // 連線FTP伺服器 ftpClient.connect(hostname, port); // 登入FTP伺服器 ftpClient.login(username, password); // 是否成功登入FTP伺服器 int replyCode = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(replyCode)) { return flag; } //ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.makeDirectory(pathname); ftpClient.changeWorkingDirectory(pathname); ftpClient.storeFile(fileName, inputStream); inputStream.close(); ftpClient.logout(); flag = true; } catch (Exception e) { e.printStackTrace(); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException e) { e.printStackTrace(); } } } long endTime=System.currentTimeMillis(); float excTime=(float)(endTime-startTime)/1000; System.out.println("執行時間:"+excTime+"s"); return flag; }
2.使用webuploader上傳,集成了進度條.
(1)前端頁面
<link rel="stylesheet" type="text/css" href="js/webuploader/webuploader.css" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="js/webuploader/style.css" />
<input type="hidden" id="fileUrl" name="news.fileUrl">
<div id="uploader" class="wu-example">
<div class="btns">
<div id="attach"></div>
<div id="thelist" class="uploader-list"></div>
<a id="upload" href="javascript:void(0)" class="easyui-linkbutton">上傳檔案</a>
</div>
</div>
<script type="text/javascript" src="js/webuploader/webuploader.js"></script>
<script type="text/javascript" src="js/webuploader/upload.js"></script>
<div style="text-align:center;clear:both;">
<script src="js/other/gg_bd_ad_720x90.js" type="text/javascript"></script>
<script src="js/other/follow.js" type="text/javascript"></script>
</div>
(2)進度條樣式檔案
body{
background: #a8b1b6;
color: #2fa0ec;
font-weight: 500;
font-size: 1.05em;
font-family: "Microsoft YaHei","宋體","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif, FreeSans, Arimo;
}
a{color: #d8dedc;outline: none;}
a:hover,a:focus{color:#74777b;text-decoration: none;}
.progress{
height: 30px;
line-height: 35px;
background: #809495;
box-shadow: none;
padding: 6px;
margin-top:20px;
overflow: visible;
border-radius:10px;
}
.progress:after{
content: "";
display: block;
border-top: 4px dashed #fff;
margin-top:8px;
}
.progressbar-title{
color:#d8dedc;
font-size:15px;
margin:5px 0;
font-weight: bold;
}
.progress .progress-bar{
position: relative;
border-radius: 10px 0 0 10px;
animation: animate-positive 2s;
}
.progress .progress-bar span{
position: absolute;
top: -50px;
right: -40px;
color: #fff;
display: block;
font-size: 17px;
font-weight: bold;
padding: 5px 7px;
background: #333;
border-radius: 0 0 5px 5px;
}
.progress .progress-bar span:before{
content: "";
position: absolute;
bottom: -14px;
left: 18px;
border: 7px solid transparent;
border-top: 7px solid #333;
}
.progress .progress-bar span:after{
content: "\f072";
font-family: fontawesome;
font-size: 48px;
color: #333;
position: absolute;
top: 51px;
right: 6px;
transform: rotateZ(48deg);
}
@-webkit-keyframes animate-positive {
0% { width: 0%;}
}
@keyframes animate-positive {
0% { width:0%; }
}
(3) 上傳檔案 upload.js
/**
* *******************************WebUpload 單檔案上傳begin****************************************
*/
_extensions ='3gp,mp4,rmvb,mov,avi,m4v,mkv';
_mimeTypes ='video/*,audio/*,application/*';
$(function() {
var $list = $("#thelist");
var uploader;// 例項化
uploader = WebUploader.create( {
auto : false, // 是否自動上傳
pick : {
id : '#attach',
name : "file", // 這個地方 name
// 沒什麼用,雖然開啟偵錯程式,input的名字確實改過來了。但是提交到後臺取不到檔案。如果想自定義file的name屬性,還是要和fileVal
// 配合使用。
label : '點選選擇檔案',
multiple : false
// 預設為true,就是可以多選
},
swf : 'js/webuploader/Uploader.swf',
// fileVal:'multiFile', //自定義file的name屬性,我用的版本是0.1.5 ,開啟客戶端偵錯程式發現生成的input
// 的name 沒改過來。
// 名字還是預設的file,但不是沒用哦。雖然客戶端名字沒改變,但是提交到到後臺,是要用multiFile 這個物件來取檔案的,用file
// 是取不到檔案的
server : "videoAction!ajaxAttachUpload.action",
duplicate : true,// 是否可重複選擇同一檔案
resize : false,
formData : {
"status" : "file",
"contentsDto.contentsId" : "0000004730",
"uploadNum" : "0000004730",
"existFlg" : 'false'
},
compress : null,
chunked : true, // 分片處理
chunkSize : 50 * 1024 * 1024, // 每片50M,經過測試,發現上傳1G左右的視訊大概每片50M速度比較快的,太大或者太小都對上傳效率有影響
chunkRetry : false,// 如果失敗,則不重試
threads : 1,// 上傳併發數。允許同時最大上傳程序數。
// runtimeOrder: 'flash',
disableGlobalDnd : true,
accept: {
title: '視訊檔案上傳', //文字描述
extensions: _extensions, //允許的檔案字尾,不帶點,多個用逗號分割。,jpg,png,
mimeTypes: _mimeTypes, //多個用逗號分割。,
}
});
// 當有檔案新增進來的時候
uploader.on("fileQueued", function(file) {
console.log("fileQueued:");
$list.html("
" + "
" + file.name + "
" + "等待上傳...
" + " "); }); // 當所有檔案上傳結束時觸發 uploader.on("uploadFinished", function() { console.log("uploadFinished:"); }); // 當某個檔案上傳到服務端響應後,會派送此事件來詢問服務端響應是否有效。 uploader.on("uploadAccept", function(object, ret) { // 伺服器響應了 var data = JSON.parse(ret._raw); if (data.isSuccess == "1" || data.isSuccess == "3") { $("#fileUrl").val(data.fileUrl); } else { uploader.reset(); alert("上傳檔案出現異常,請重新整理後重新嘗試。"); return false; } }); uploader.on('uploadProgress', function (file, percentage) {//進度條事件 var $li = $list.find('#' + file.id), $percent = $li.find('#ProcessWD'); // 避免重複建立 if (!$percent.length) { $percent = $('上傳進度
' + ' ' + ' ' + ' ').appendTo($li).find('.progress-bar'); } $("#" + file.id).find("p.state").text('正在上傳'); $("#fileProcess").text(Math.round(percentage * 100) + '%'); $("#ProcessWD").css('width', percentage * 100 + '%'); }); // 當檔案上傳成功時觸發。 uploader.on("uploadSuccess", function(file) { $("#" + file.id).find("p.state").text("已上傳成功"); }); uploader.on("uploadError", function(file) { $("#" + file.id).find("p.state").attr("color","red"); $("#" + file.id).find("p.state").text("上傳出錯"); uploader.cancelFile(file); uploader.removeFile(file, true); uploader.reset(); }); /** * 驗證檔案格式以及檔案大小 */ uploader.on("error",function (type,handler){ if (type=="Q_TYPE_DENIED"){ $.messager.alert('提示視窗','請上傳MP4格式的視訊!'); } }); $("#upload").on("click", function() { $("#showJD").attr("display","block"); $('#upload').linkbutton('disable'); uploader.upload(); }) });(4) 後臺上傳處理
//視訊檔案上傳
private File file;
private String fileFileName;
//屬性值,接收webupload自帶的引數
private String chunk; // 當前第幾個分片
private String chunks;// 總分片個數
private String size;// 單個檔案的總大小
......
/**
* 檔案上傳儲存
* @return
*/
public String ajaxAttachUpload() {
Map<String, Object> map = new HashMap<String, Object>();
try {
String fileUrl = CommonConstants.UPLOAD_VIDEO +fileFileName;
fileUrl = fileUrl.replace("\\", "/");
FileUtil.randomAccessFile(fileUrl,file);
if(EmptyUtils.isEmptyString(chunk)){
map.put("isSuccess", 1);//不分片的情況
}else{
if (Integer.valueOf(chunk) == (Integer.valueOf(chunks) - 1)) {//分片的情況
map.put("isSuccess", 1);
} else {
map.put("isSuccess", 3);
}
}
map.put("fileUrl", saveDir);
} catch (Exception e) {
map.put("isSuccess", 2);
}
request.setAttribute("records", JSONObject.fromObject(map));
return "back";
}
.......
/**
* 指定位置開始寫入檔案
* @param tempFile 輸入檔案
* @param outPath 輸出檔案的路徑(路徑+檔名)
* @throws IOException
*/
public static void randomAccessFile(String outPath,File tempFile) throws IOException{
RandomAccessFile raFile = null;
BufferedInputStream inputStream=null;
try{
File dirFile = new File(outPath);
File parentDir = dirFile.getParentFile();
if (!parentDir.exists()) {
FileUtils.forceMkdir(parentDir);
}
//以讀寫的方式開啟目標檔案
raFile = new RandomAccessFile(dirFile, "rw");
raFile.seek(raFile.length());
inputStream = new BufferedInputStream(new FileInputStream(tempFile));
byte[] buf = new byte[1024];
int length = 0;
while ((length = inputStream.read(buf)) != -1) {
raFile.write(buf, 0, length);
}
}catch(Exception e){
e.printStackTrace();
throw new IOException(e.getMessage());
}finally{
try {
if (inputStream != null) {
inputStream.close();
}
if (raFile != null) {
raFile.close();
}
}catch(Exception e){
throw new IOException(e.getMessage());
}
}
}
(5)視訊檢視
<video width="75%" controls="controls" autoplay="autoplay">
<source src="${pageContext.request.contextPath}/${n.fileUrl}" type="video/ogg" />
<source src="${pageContext.request.contextPath}/${n.fileUrl}" type="video/mp4" />
您的瀏覽器不支援此種視訊格式。
</video>
使用ftp上傳大檔案太慢了,最後選擇了百度的webuploader,測試下來效果還不錯。
以上