遇到一个需求,用户想上传超过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,测试下来效果还不错。
以上