WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。
上面的一段话是来自 http://fex.baidu.com/webuploader/ 的介绍,现在做的项目需要用到大文件的上传,之前没有做过,现有的jquery的uploadify只用于上传图片什么的小文件,查了网上的资料,这个插件好像对于大文件不是很友好,为了安全起见,使用百度的成熟框架,不论是多文件还是单个的大文件都是很好用的,没有很多的问题,关于webuploader的详细介绍看官网就行:
我的项目是javaweb,开发环境是MyEclipse,页面使用jsp
根据个人的需求放置自己需要的东西就行,全部放到项目里也可以,下面是我自己需要的东西:
//这个id是你要点击上传文件的id,自己设置就好
multiple:false},
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: true,
auto:true,
//开启分片上传
chunked: true,
chunkSize:10*1024*1024,
accept: {
//限制上传文件为MP4
extensions: 'mp4',
mimeTypes: 'video/mp4',
}
});
// 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$('#item1').empty();
$('#item1').html(''
);
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
$('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');
});
uploader.on( 'uploadSuccess', function( file ) {
$( '#'+file.id ).find('p.state').text('已上传');
});
uploader.on( 'uploadError', function( file ) {
$( '#'+file.id ).find('p.state').text('上传出错');
});
uploader.on( 'uploadComplete', function( file ) {
$( '#'+file.id ).find('.progress').fadeOut();
});
function start(){
uploader.upload();
$('#btn').attr("onclick","stop()");
$('#btn').text("取消上传");
}
function stop(){
uploader.stop(true);
$('#btn').attr("onclick","start()");
$('#btn').text("继续上传");
}
servlet部分需要两个servlet,一个用于接收分块文件,一个用于合并分块成一个文件:
1、接收分块servlet代码:
@SuppressWarnings("serial")
public class UploadVideo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
doPost(req, resp);
}
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(factory);
sfu.setHeaderEncoding("utf-8");
String savePath = this.getServletConfig().getServletContext()
.getRealPath("");
String folad = "uploads";
savePath = savePath + "\\"+folad+"\\";
String fileMd5 = null;
String chunk = null;
try {
List items = sfu.parseRequest(request);
for(FileItem item:items){
if(item.isFormField()){
String fieldName = item.getFieldName();
if(fieldName.equals("fileMd5")){
fileMd5 = item.getString("utf-8");
}
if(fieldName.equals("chunk")){
chunk = item.getString("utf-8");
}
}else{
File file = new File(savePath+"/"+fileMd5);
if(!file.exists()){
file.mkdir();
}
File chunkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、合并分块servlet代码:
@SuppressWarnings("serial")
public class Video extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
super.doGet(request, response);
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String savePath = this.getServletConfig().getServletContext()
.getRealPath("");
String folad = "uploads";
savePath = savePath + "\\"+folad+"\\";
String action = request.getParameter("action");
if(action.equals("mergeChunks")){
//合并文件
//需要合并的文件的目录标记
String fileMd5 = request.getParameter("fileMd5");
//读取目录里的所有文件
File f = new File(savePath+"/"+fileMd5);
File[] fileArray = f.listFiles(new FileFilter(){
//排除目录只要文件
@Override
public boolean accept(File pathname) {
// TODO Auto-generated method stub
if(pathname.isDirectory()){
return false;
}
return true;
}
});
//转成集合,便于排序
List fileList = new ArrayList(Arrays.asList(fileArray));
Collections.sort(fileList,new Comparator() {
@Override
public int compare(File o1, File o2) {
// TODO Auto-generated method stub
if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){
return -1;
}
return 1;
}
});
//UUID.randomUUID().toString()-->随机名
File outputFile = new File(savePath+"/"+fileMd5+".mp4");
//创建文件
outputFile.createNewFile();
//输出流
FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();
//合并
FileChannel inChannel;
for(File file : fileList){
inChannel = new FileInputStream(file).getChannel();
inChannel.transferTo(0, inChannel.size(), outChnnel);
inChannel.close();
//删除分片
file.delete();
}
outChnnel.close();
//清除文件夹
File tempFile = new File(savePath+"/"+fileMd5);
if(tempFile.isDirectory() && tempFile.exists()){
tempFile.delete();
}
System.out.println("合并成功");
}else if(action.equals("checkChunk")){
//检查当前分块是否上传成功
String fileMd5 = request.getParameter("fileMd5");
String chunk = request.getParameter("chunk");
String chunkSize = request.getParameter("chunkSize");
File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
response.setContentType("text/html;charset=utf-8");
//检查文件是否存在,且大小是否一致
if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){
//上传过
response.getWriter().write("{\"ifExist\":1}");
}else{
//没有上传过
response.getWriter().write("{\"ifExist\":0}");
}
}
}
}
至此,大文件上传的分块和断点就ok了,这也只是我自己的项目需求编写的,这个框架还涵盖很多的内容和功能,需要你自己去研究了,不过都不是很难,你也可以去修改它的css和js文件根据自己的需求。