关于 断点续传上传与秒传 你绕不过去的坎 html5+php

qq_34028302 2016-02-23 07:48:27
加精

超大文件上传就无法避免断点上传,想要实现秒传你就饶不开文件特征。本文不涉及具体代码。只讲我自己对断点上传于秒传的学习经验。
首先我们分析一下要实现断点续传于秒传的具体要点。

1、前端拆分碎片
2、前端生成文件特征
3、传输过程
4、后台接收文件合并
5、合并完成后,后台的特征对比

看似原理简单,粗狂分析一下就可以动手了,其实每一步都有很多技术难点于陷阱。

1、前端拆分文件碎片

在以前只要断点续传就必须采用前端控件。控件主要工作就是在拆分文件与碎片与分析md5。现在的html5本身已经支持对文件拆分读取上传。至于如何拆分自己搜索一下很容易找到demo。这里陷阱不多只要考虑一下兼容性就可以了,IE系列可以考虑用flash。

2、前端生成文件特征

这里说明一下,我没有直接说是md5 是因为md5现在在大型网盘项目里碰撞的几率已经很高了,不能完全依赖md5,尽量多取几种哈西值一起传到后端做特征。(取文件的几部分做特征是很不靠谱的不用考虑了)

在前端生成特征才能实现秒传功能(也许有不需要的方法反正我不知道)。文件生成哈西值,是采用流运算方式把整个文件读取分析一遍。由于需要读取,那么超大文件的耗时是不可避免的。目前js 有个很好的库类可以支持采用文件流方式计算md5 。spark-md5.js 这是个好东西。只需要把文件碎片挨个分析一遍,文件全部跑完就能生成一个md5了理论上可以生成任意大小文件的md5。测试过8G的文件生成一个md5码需要十几分钟。这取决于客户机器性能和磁盘速度。网上还有其他哈西的文件流获取算法,请自行百度。

3、传输

传输现在html5现在可以采用ajax和websocket两种方式可以任选。这里我选用的是自己熟悉的ajax方式,websocket只是初略的看了一下。就不发表具体看法了。
ajax生成传输队列的时候有个坑需要注意一下。当拆分碎片上传,也就是每一个碎片是一个ajax请求。那么一个8G的文件将会生成多少请求呢。一个循环下去浏览器死了。所以要采用递归方式进行控制ajax堵塞数量。一次循环传输10个碎片,传完在传下一组。

4、后台的文件合并。
接收到文件就需要考虑合并问题了。我之前百度了一下。基本都告诉我等待文件碎片全部上传完成然后合并。当我上传一个8G的文件到后台后然后循环合并,太恐怖了上万的碎片合并。想想就难受。
第一个想法是放到队里里在后面慢慢跑。后来放弃了感觉体验不是很好。
后来想到了边上传边合并,把合并时间分散到每一个请求里。每个请求只处理1-2mb的碎片还是很快的。
刚开始参考迅雷想生成一个和目标文件体积相等的空白文件。然后等待碎片来拼入文件。后来发现php不能快速干这个事情。有其他方法也懒着研究了。就写了一个扩容算法
算法说明:
收到请求后如果第一个碎片是2号,那么在生成的文件里填充字符串把1号碎片的位置留下,然后写入2号碎片,等1号碎片 达到,在把1号碎片写入他自己的位置。

算法基本上很快没有什么延时。好在我们不是做下载,上传时不会直接收到最后的碎片。

写好后进行测试发现文件大于2g就不在生成了。块是很快了不过不能处理大文件。后来发现是php文件指针在32位系统下最大值是2G。如果移动大于2G 就会返回-1失败。那么理论上这个算法最大生成文件是2G。(或者是4G ,指针从文件尾巴向前计算还有2g不过我没有继续研究下去,理论上php读取文件内容最大值是4G)下面换一种算法。

最简单的办法,就是往文件尾巴里追加内容,这样就不受文件指针大小影响了。ajax 在并发的时候到达顺序是不一样的。但是这个不影响,不会对我们后台编程产生太大的障碍。后台进行搬砖一样的排序写入就好了,。
举例:
如果是第一个碎片收到的是2号,那么把碎片文件拷贝出来备用。
下一个请求碎片如果是1那么写入文件,写入后询问备用里有没有2号如果有写入。以此类推。

这个算法和上面的扩容方法比起来效率要低了一些。因为要做计数器和询问利用。但是影响不是很大。
我两种算法都采用了如果文件小于1.99g用上面得扩容算法,大于就用排序。
合并也完成了剩下就是对结果进行效验了。

5、后台文件效验。
不要相信 php 或者其他语言的 md5_file这玩意处理不来大文件。几个G基本上就崩溃了。记住一点只要你想获得文件的md5 ,就必须对这个文件进行读取分析一遍才行怎么做都是很耗时的。
像百度那种大型网盘已经完成对TB级别md5随时生成,真的很牛叉。后来我分析了一下他们应该是这么做的。

应该和我们处理文件合并的方式差不多。把计算md5的时间分摊到了每一个碎片上。我们可以这么理解,md5 需要顺序分段读取整个文件进行分析才能生成一个md5值,那么我们在上传过程中每一个碎片都是文件的一部分。我们只要顺序分析每一个文件碎片,那么上传完成了md5也就生成了(理论上也能到TB级别)。

我尝试用这种方式找了一个php 版本的md5算法,改进了一下,实现了超级大文件上传完成后台即使获得到md5的类。(测试过与 md5_file函数获得的值一样.)
经过测试完全可行。 "但是,可但是,但可是" php真的不适合干这种大型纯运算很慢,基本上js 算md5的效率 是php几十倍。一个2mb的碎片计算需要9秒左右。
这么做每一个碎片后台响应时间都超长,也就直接影响上传速度了。
几经研究无果。决定放弃php 找师哥用c写个扩展来干这个事情了。

项目基本完成了,至于其他的续传 和 秒传 没什么好讲的,你都已经有碎片了续传不是问题。你都能获得前后端特征码了,那么秒传也不是问题了。


这个过程最耗时的是前端计md5,其他运算都分摊到每一碎片上了。



上面的东西没有经过大小项目验证全是理论上的,也许我是错的。我说的都是我自己理解的有错误的地方请指出,我会改进不要误导群众。
如果有需要探讨的加我QQ吧 1 2 2 1 3 8 2 9 9
...全文
6473 21 打赏 收藏 举报
写回复
21 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
weixin_43869905 2019-09-17
nb.nb 说得真好 我都看不太懂
  • 打赏
  • 举报
回复
文盲老顾 2019-09-17
  • 打赏
  • 举报
回复
hookee 2019-09-17
  • 打赏
  • 举报
回复
qq_34028302 2019-09-16
https://download.csdn.net/download/qq_34028302/9437555 demo 下载
  • 打赏
  • 举报
回复
HQChart 2019-06-19
如果只是 下载和上传应该不需要, 在服务器上合并文件的吧, 下载还是根据上传的分块下载的。
  • 打赏
  • 举报
回复
y_w_x_k 2019-06-18
先留名,以后再看
  • 打赏
  • 举报
回复
于小九 2019-06-17
哈哈哈,超级大文件上传完成后台即使获得到md5的类楼楼可以分享一下学习学习吗
  • 打赏
  • 举报
回复
素材火 2017-09-29
刚写一个PHP断点上传DEMO,分享给大家:http://www.sucaihuo.com/php/3102.html
  • 打赏
  • 举报
回复
失散糖 2016-02-28
后台的文件为啥要合并呢,就弄一大堆文件碎片摆在那里如何
  • 打赏
  • 举报
回复
haoqingwang 2016-02-25
路过,但很受启发
  • 打赏
  • 举报
回复
line_us 2016-02-25
看看实现断点续传于秒传的具体要点
  • 打赏
  • 举报
回复
wyx3010218151 2016-02-24
引用 8 楼 dear_Alice_moon 的回复:
路过,长知识了。 今年年初时,因为我要下载一款由Sun公司研发的ISO镜像文件。下载好多次没有都出现断点续传问题,弄得我头疼的不得了。用迅雷下载不顶用,后得到高人指点自己在晚上找了一款国外的支持断点续传的工具。中间出现了3次断点中断,之后我又将其从断点处开始,终于将我想要的那份文件下载下来了。感觉棒棒哒,哈哈。
  • 打赏
  • 举报
回复
_明月 2016-02-24
路过,长知识了。 今年年初时,因为我要下载一款由Sun公司研发的ISO镜像文件。下载好多次没有都出现断点续传问题,弄得我头疼的不得了。用迅雷下载不顶用,后得到高人指点自己在晚上找了一款国外的支持断点续传的工具。中间出现了3次断点中断,之后我又将其从断点处开始,终于将我想要的那份文件下载下来了。感觉棒棒哒,哈哈。
  • 打赏
  • 举报
回复
zj198828 2016-02-24
不错
  • 打赏
  • 举报
回复
强好强 2016-02-24
  • 打赏
  • 举报
回复
雨网科技 2016-02-24
  • 打赏
  • 举报
回复
cattpon 2016-02-24
看看是什么~
  • 打赏
  • 举报
回复
blueink_200451 2016-02-24
路过学习了。涨了知识了。
  • 打赏
  • 举报
回复
业余草 2016-02-24
  • 打赏
  • 举报
回复
shiter 2016-02-24
之前只是知道是md5,但确实不知道是怎么做的
  • 打赏
  • 举报
回复
相关推荐
课程设计-基于C++的mfc框架的学生社团管理系统(源码+数据库+报告).zip 本系统实现的功能 本程序为单文档应用程序,主程序界面能实现查询社团信息、修改社团信息、删除社团信息、添加社团信息、入团、退团、用户登录、和用户管理功能其中修改社团信息、删除社团信息、添加社团信息和用户管理需要用户登录后才能使用,未登录就点击使用的会会弹出对话框显示您还没有登录,点击登录按钮会弹出用户登录对话框输入正确的用户名称和密码若验证成功则会显示登录成功并显示出您用有的权限高级管理员或者是普通管理员,高级管理员则可以对社团信息进行修改、删除、添加。点击入团按钮会弹出加入社团对话框,在对话框内填上相应的信息后点击确定成功加入后会有相关提示,若没有成功则有可能您输入的社团存在,点击退团按钮弹出退出社团对话框,输入您要退出的社团名称和学号点击确定如果成功退出会显示成功的标志,否则的话就是您没有假如该社团活着您填的信息完全。在主程序对话框中可以直接在控件内输入要修改的社团信息,然后点击修改按钮,分别输入控件中的内容然后点击添加按钮,若要添加的社团当前没有的话则添加成功,否则会失败。登录了以后点击用户管理按钮则会弹出用户管理对话框,在该对话框内可以修改用户密码,高级管理员还能注册新用户。
发帖
HTML5
加入

3.8w+

社区成员

HTML5是构建Web内容的一种语言描述方式。HTML5是互联网的下一代标准,是构建以及呈现互联网内容的一种语言方式.被认为是互联网的核心技术之一。
社区管理员
  • HTML5社区
申请成为版主
帖子事件
创建了帖子
2016-02-23 07:48
社区公告
暂无公告