1.刚开始接触mongodb,然后查询到PHP的DRIVER并不支持HTTP RANGE header,这样就无法支持断点续传,不知道该如何查询下去,不知道最近的mongoDB的php client有没有支持这个?
2.我自己想着应该可以用mongodb的chunks来实现一种断点续传,每个块默认是256K,程序根据自己下载的文件大小判断下载了多少个块,然后再请求下一块,遇到下载的chunks不是整数,删除不是整数的那一部分,然后从整数+1的那一个chunks继续下载。这种方案是否可行呢?
怪我咯2017-04-10 14:25:46
关于php、关于HTTP RANGE、关于断点续传
其实比较憋屈,文件服务器做的事让php去做了。如果是大文件,用fread一下子全部读出来,php基本会抛出异常,提示内存不够。那这里还要去控制一个读出限制。
比如我前面说那例子中是这么处理的(我简化了部分)。每次读出最多1024 * 8个字节数,到达EOF 的时候完成。
// Start buffered download $buffer = 1024 * 8; while(!feof($fp)) { set_time_limit(0); // Reset time limit for big files echo fread($fp, $buffer); flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit. } fclose($fp);
可以想象下,如果服务器(不管是ftp还是http等等)他们不允许断点。那些众多的下载软件基本没市场了。目的服务器支持多线程最好了,如果不允许也没关系,到其他下载点返回一个断点,继续下载,自己实现一个多断点下载。这也是下载软件的基本原理。
Gridfs Mongodb存储
你所描述的“用mongodb的chunks来实现一种断点续传”这是错误的理解。断点这不关数据库的事。你所描述的是一个读取过程,控制的一个数据输出。并且因为HTTP本身协议原因,它没能力让你“删除不是整数的部分”你只能判断出具体文件字节流,再做细致数据输出。
其实你应该往”Gridfs Mongodb存储“方向去做应用。
gridfs就是做你所描述的类似的事情。将文件分割存储到mongodb。读出时再整合。其中内部机制我没研究,但肯定比你自己实现要有效率的多。你如果有兴趣可以去研究下。针对php的mongodb驱动也是评价非常好的。使用gridfs替换原始文件存储是可行的。
并且如果你使用的是Nginx服务器软件,可以避开php读取。直接做成Nginx模块。让Nginx去读取文件,会比使用php更高效。当然了写入还是用php。
HTTP 断点上传有难度,单纯的依靠它自身实现不了。目前的方案挺多:java、flash、silverlight、activex等等做客户端控制,然后服务器端再做处理等等。目前我知道的做的比较优秀的是Youtube:https://support.google.com/youtube/bi... (需要翻一下)
高洛峰2017-04-10 14:25:46
从原理上说,GridFS至少应该支持按照Chunk来读写,所以断点续传是可以实现的。但是由于目前的php sdk里头没有细化到chunk这一层,所以如果需要这么做的话,可能得自己改改。
巴扎黑2017-04-10 14:25:46
mongodb 的 chunks 写入后不支持修改,所以你要注意到如果 chunks 尺寸过大会让你在下次传递的时候丢失一部分数据,上传客户端也先要从服务器获取已经上传的 chunks 的数量乘以尺寸为续传应该开始的地方。