大文件上传第三弹(分片、秒传、断点续传)


目录

背景介绍

项目介绍

使用说明 

  获取代码 

  需要知识点 

  启动项目 

  项目示范

核心讲解 

  重要原理

功能分析 

  分块上传 

  秒传功能 

  断点续传

总结

背景介绍

  up6。这是一个大文件上传的产品。该项目是基于荆门泽优的上传控件:HttpUploader6。它支持大文件上传(1G~20G+)和文件夹上传。是目前国内上传产品中做的最好的,无论是代码质量还是开发文档都是我见过的同领域中最好的。强烈推荐企业和公司使用。真的能够为企业节省不少人力成本,也为开发人员节省少少时间。

项目介绍

  up6是一个基于大文件上传,并参考网盘上传文件,而基于web的大文件上传实现项目。web中上传大文件没有桌面软件那么容易,还好现在是身处于一个html5的时代。我们web端上传文件常用的做法就是用表单上传了,一旦上传的文件大小较大,一旦带宽跟不上,那用户只能在哪里一直等着,不能做刷新页面的操作,并且一旦产生网络波动,那么用户所做的一切就白费了。 

  up6就是为了保证在web端上传大文件能达到基本的可靠性的一种方案,方法多种,可能的方案会更出色,欢迎讨论。要让大文件上传能达到可用性,我们需要做到怎么样的程度呢? 

  * 断点续传 最主要的功能之一,在断网或者在暂停的情况下,能够在上传断点中继续上传。 

  * 文件夹上传 最主要的功能之一,能够直接上传整个文件夹,且自动处理层级关系,能够直接保存在数据库中,且支持文件夹MD5验证,文件夹秒传。

  * 分块上传 也是断点续传的基础之一,把大文件通过前端分块,然后后台在组在一起。 

  * 文件秒传 能够自动检测重复文件,帮助服务器节省存储空间,帮助用户节省上传时间。

  * 其他功能 把下面这些功能归类到其他,是因为它们基本都是通过up6(http://www.ncmem.com/v2/webapp/up6/index.aspx)来实现的,很简单。 

   - 多线程上传 多个线程上传不同的块文件。 

   - 文件进度显示 显示文件的上传完成情况。 

   -  自定义UI 能够根据项目需求修改UI

   -  自定义事件 能够根据项目需求增加或修改事件

   -  可扩展性 能够根据项目需求增加或修改业务参数

使用说明

获取代码

在线代码(GitHub)asp.net,jsp-oracle,jsp-mysql,jsp-sql,php-mysql

在线代码(coding)asp.net,jsp-oracle,jsp-mysql,jsp-sql,php-mysql

在线代码(oschina)asp.net,jsp-oracle,jsp-mysql,jsp-sql,php-mysql

在线代码(csdn)asp.net,jsp-oracle,jsp-mysql,jsp-sql,php-mysql

持续更新。

需要知识点

基于jquery+html开发的。

启动项目

本地测试

jsp-mysqlhttp://bbs.ncmem.com/thread-291-1-1.html

jsp-oraclehttp://bbs.ncmem.com/thread-192-1-1.html

jsp-sqlhttp://bbs.ncmem.com/thread-222-1-1.html

php-windowshttp://bbs.ncmem.com/thread-112-1-1.html

php-linuxhttp://bbs.ncmem.com/thread-298-1-1.html

asp.nethttp://bbs.ncmem.com/thread-193-1-1.html

项目示范

1.文件扫描界面

http://res2.ncmem.com/res/images/up6.2/file-md5.png

 

2.秒传界面

http://res2.ncmem.com/res/images/up6.2/file-md5-exist.png

 

3.文件夹上传

http://res2.ncmem.com/res/images/up6.2/fd-post.png

 

核心讲解

核心原理

  该项目核心就是文件分块上传。前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题。 

  * 如何分片; 

  * 如何合成一个文件; 

  * 中断了从哪个分片开始。 

  如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子。但是因为时间的关系还有工作的关系,我只能罢休了。最后我选择了荆门泽优的HttpUploader6来实现前端所需。 

功能分析

分块上传

  分块上传可以说是我们整个项目的基础,像断点续传、暂停这些都是需要用到分块。 

分块这块相对来说比较简单。前端是采用了up6,分块等基础功能已经封装起来,使用方便。 

借助up6提供给我们的文件API,前端就显得异常简单。

    <script language="javascript" type="text/javascript">

        var cbMgr = new HttpUploaderMgr();

        cbMgr.event.md5Complete = function (obj, md5) { /*alert(md5);*/ };

        cbMgr.event.fileComplete = function (obj) { /*alert(obj.pathSvr);*/ };

        cbMgr.event.queueComplete = function () { /*队列上传完毕*/ };

        cbMgr.event.addFdError = function (jv) { alert("本地路径不存在:" + jv.path); };

 

    $(function()

    {

            cbMgr.load_to("FilePanel");

            //上传指定文件

            $("#btnUpF").click(function () {

                var path = $("#filePath").val();

                cbMgr.app.addFile({ pathLoc: path });

            });

            //上传指定目录

            $("#btnUpFd").click(function () {

                var path = $("#folderPath").val();

                cbMgr.app.addFolder({ pathLoc: path });

            });

    });

    </script>

文件合并也非常简单,up6默认是将多个分块数据写入到一个文件中,所以这块不需要开发人员再手动合并了。

String uid         = request.getHeader("uid");//

String id          = request.getHeader("id");

String md5         = request.getHeader("md5");

String lenSvr      = request.getHeader("lenSvr");

String lenLoc      = request.getHeader("lenLoc");

String blockOffset = request.getHeader("blockOffset");

String blockSize   = request.getHeader("blockSize");

String blockIndex  = request.getHeader("blockIndex");

String complete    = request.getHeader("complete");

String pathSvr     = request.getHeader("pathSvr");

pathSvr = PathTool.url_decode(pathSvr);

 

//参数为空

if(  StringUtils.isBlank( uid )

     || StringUtils.isBlank( id )

     || StringUtils.isBlank( blockOffset )

     || StringUtils.isBlank(pathSvr))

{

     XDebug.Output("param is null");

     return;

}

 

// Check that we have a file upload request

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory = new DiskFileItemFactory();  

ServletFileUpload upload = new ServletFileUpload(factory);

List files = null;

try

{

     files = upload.parseRequest(request);

}

catch (FileUploadException e)

{// 解析文件数据错误 

    out.println("read file data error:" + e.toString());

    return;

  

}

 

FileItem rangeFile = null;

// 得到所有上传的文件

Iterator fileItr = files.iterator();

// 循环处理所有文件

while (fileItr.hasNext())

{

     // 得到当前文件

     rangeFile = (FileItem) fileItr.next();   

}

 

//文件块验证

if(Integer.parseInt(blockSize) == rangeFile.getSize())

{

     //保存文件块数据

     FileBlockWriter res = new FileBlockWriter();

     res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);

     rangeFile.delete();

     out.write("ok");

}

else

{

     rangeFile.delete();

     out.write("block size error");

}

秒传功能

  秒传功能,相信大家都体现过了,网盘上传的时候,发现上传的文件秒传了。其实原理稍微有研究过的同学应该知道,其实就是检验文件MD5,记录下上传到系统的文件的MD5,在一个文件上传前先获取文件内容MD5值或者部分取值MD5,然后在匹配系统上的数据。 

  up6实现秒传原理,用户选择文件后控件将会自动开启扫描线程开始计算文件MD5,扫描完毕后将会触发一个事件通知UI层,UI向服务器发送ajax请求查询数据库中是否已经存在相同MD5

DBFile db = new DBFile();

FileInf fileExist = new FileInf();

 

boolean exist = db.exist_file(md5,fileExist);

//数据库已存在相同文件,且有上传进度,则直接使用此信息

if(exist && fileExist.lenSvr > 1)

{

     fileSvr.pathSvr    = fileExist.pathSvr;

     fileSvr.perSvr     = fileExist.perSvr;

     fileSvr.lenSvr     = fileExist.lenSvr;

     fileSvr.complete   = fileExist.complete;

     db.Add(fileSvr);

}//此文件不存在

else

{

     db.Add(fileSvr);

    

     FileBlockWriter fr = new FileBlockWriter();

     fr.CreateFile(fileSvr.pathSvr);     

}

 

断点续传

  断点续传,就是在文件上传的过程中发生了中断,人为因素(暂停)或者不可抗力(断网或者网络差)导致了文件上传到一半失败了。然后在环境恢复的时候,重新上传该文件,而不至于是从新开始上传的。 

  前面也已经讲过,断点续传的功能是基于分块上传来实现的,把一个大文件分成很多个小块,服务端能够把每个上传成功的分块都落地下来,客户端在上传文件开始时调用接口快速验证,条件选择跳过某个分块。 

  up6在断点续传这块做的已经非常完善了,完全不需要开发人员再进行多余的操作。全自动化的处理。服务器也不需要额外处理,DEMO中就已经处理好了。

总结

  up6无论是用来传文件还是用来传文件夹都是非常方便的,这为企业节省了相当多的时间成本和人力成本。对于开发人员来讲,up6有相当良好的接口设计,及参数扩展框架。可以非常方便的集成到其它的web系统中。

  由于时间有限,所以就在这里大概介绍一些基础的东西,如果各位朋友想了解更具体的建议下载DEMO体验一下,谢谢大家。

参考文献

[1]http://www.ncmem.com/doc/up6/index.aspx

[2]http://www.cnblogs.com/xproer/category/355072.html

[3]http://www.cnblogs.com/xproer/archive/2012/02/17/2355469.html



猜你喜欢

转载自blog.csdn.net/activexme/article/details/80987224