1.剛開始接觸mongodb,然後查詢到
PHP的DRIVER並不支援HTTP RANGE header,這樣就無法支援斷點續傳,不知道該如何查詢下去,不知道最近的mongoDB的php client有沒有支援這個?
2.我自己想著應該可以用mongodb的chunks來實現一種斷點續傳,每個塊預設是256K,程式根據自己下載的檔案大小判斷下載了多少個塊,然後再請求下一塊,遇到下載的chunks不是整數,刪除不是整數的那一部分,然後從整數+1的那一個chunks繼續下載。這種方案是否可行呢?
回複內容:
1.剛開始接觸mongodb,然後查詢到PHP的DRIVER並不支援HTTP RANGE header,這樣就無法支援斷點續傳,不知道該如何查詢下去,不知道最近的mongoDB的php client有沒有支援這個?
2.我自己想著應該可以用mongodb的chunks來實現一種斷點續傳,每個塊預設是256K,程式根據自己下載的檔案大小判斷下載了多少個塊,然後再請求下一塊,遇到下載的chunks不是整數,刪除不是整數的那一部分,然後從整數+1的那一個chunks繼續下載。這種方案是否可行呢?
關於php、關於HTTP RANGE、關於斷點續傳
- 從php手冊上看$_SERVER數組的資訊是從Web伺服器建立的資訊擷取,並不關php是否支援,要看你用的web伺服器軟體是否允許。雖然手冊上並沒有列出HTTP_RANGE資訊。但是相關的例子不少。我看到寫的較嚴謹的例子:http://www.thomthom.net/blog/2007/09/...
- 你可以自己本地建立一個簡易測試。比如使用它做現成測試:http://php.net/manual/zh/function.fre...
- 下載檔案,暫停再點繼續。如果沒有做斷點續傳是回到初始重新開始或者下載器報異常(你可刪除相關http_range代碼,驗證一個事實)。事實上是php做斷點續傳是可行的。
其實比較憋屈,檔案伺服器做的事讓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... (需要翻一下)
從原理上說,GridFS至少應該支援按照Chunk來讀寫,所以斷點續傳是可以實現的。但是由於目前的php sdk裡頭沒有細化到chunk這一層,所以如果需要這麼做的話,可能得自己改改。
mongodb 的 chunks 寫入後不支援修改,所以你要注意到如果 chunks 尺寸過大會讓你在下次傳遞的時候丟失一部分資料,上傳用戶端也先要從伺服器擷取已經上傳的 chunks 的數量乘以尺寸為續傳應該開始的地方。