使用webuploader上传大文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xingfuzhijianxia/article/details/70256897

遇到一个需求,用户想上传超过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>

扫描二维码关注公众号,回复: 4792280 查看本文章

使用ftp上传大文件太慢了,最后选择了百度的webuploader,测试下来效果还不错。


以上

猜你喜欢

转载自blog.csdn.net/xingfuzhijianxia/article/details/70256897