分片上傳功能支持將一個文件切割為一系列特定大小的小數據片,分別將這些小數據片分別上傳到服務端,全部上傳完后再在服務端將這些小數據片合并成為一個資源。[上傳模型](http://developer.qiniu.com/docs/v6/api/overview/up/upload-models.html "上傳模型")中對分片上傳的特點進行了完整的闡述。
## 關鍵概念
分片上傳引入了兩個概念:**塊**(block)和**片**(chunk)。每個**塊**由一到多個**片**組成,而一個資源則由一到多個**塊**組成。他們之間的關系可以用下圖表述:

**塊**是服務端的永久數據存儲單位,**片**則只在分片上傳過程中作為臨時存儲的單位。服務端會以約一個月為單位周期性的清除上傳后未被合并為塊的數據片。
## 基本流程
與分片上傳相關的API有這幾個:[創建塊(mkblk)](http://developer.qiniu.com/docs/v6/api/reference/up/mkblk.html)、[上傳片(bput)](http://developer.qiniu.com/docs/v6/api/reference/up/bput.html)、[創建資源(mkfile)](http://developer.qiniu.com/docs/v6/api/reference/up/mkfile.html)。一個完整的分片上傳流程可用下圖表示:

其中的關鍵要點如下:
1. 將待上傳的文件按預定義的4MB塊大小切分為若干個塊。如果這個文件小于4MB,當然也就只有一個塊;
2. 將每個塊再按預定義的片大小切分為若干個片,先在服務端創建一個相應塊(通過調用[mkblk](http://developer.qiniu.com/docs/v6/api/reference/up/mkblk.html),并帶上第一個片的內容),然后再循環將所有剩下的片全部上傳(通過調用[bput](http://developer.qiniu.com/docs/v6/api/reference/up/bput.html),從而完成一個塊的上傳);
3. 在所有塊上傳完成后,通過調用[mkfile](http://developer.qiniu.com/docs/v6/api/reference/up/mkfile.html)將這些上傳完成的塊信息再嚴格的按順序組裝出一個邏輯資源的元信息,從而完成整個資源的分片上傳過程。
如要更準確的理解這個基本流程,可以通過閱讀SDK源代碼。所有SDK的源代碼都公開托管在[Github](http://github.com/qiniu)上。
## 并發上傳
由于之前介紹的片上傳過程中的Context機制,每個塊內部只能按順序逐一上傳該塊所切分好的片。而每個塊之間相互獨立,因此若干個塊可以同時進行傳輸而不會相互干擾,因此我們可以利用這個特征實現并發上傳特性。
每個文件對應的最大理論并發上傳數量也即該文件可劃分的塊數量。當然這個理論數量也受到很多其他因素的制約,比如像iOS限定了每個APP最多只能開4個并發HTTP連接,也即在iOS上,無論有多少個塊,最大的并發上傳數量不可能超過4個。并不是并發數量越大上傳速度就會越快。因此在實際開發中,通常會使用線程池(Thread Pool)技術來控制并發數量。
## 斷點續傳
雖然片的存在周期并非永久,但已足以實現斷點續傳機制。
每成功上傳一個片,客戶端都會收到服務端返回一個代表當前已上傳多少片的進度信息,我們稱之為Context。上傳下一個片時應提供前一個片上傳成功后返回的Context。因此,這個Context可以認為是片傳輸進度的一個標記。
如果上傳過程中,服務端發現一個塊已經被片數據裝滿,那么最后一個片上傳成功后返回的Context將是一個特殊的值`EOB`,告訴客戶端不要再往這個塊附加更多的片。
如果客戶端在每次收到Context信息時都將其持久化到本地,即使客戶端程序意外崩潰或正常重啟,都可以在啟動時讀取上一次上傳成功的片對應的Context,從而接著繼續傳輸剩余片。這個效果我們稱之為斷點續傳。
斷點續傳功能在上傳一個需要較長時間比如一天時間才能上傳完畢的大文件時尤其有價值,畢竟我們很難保證這段很長的時間內客戶端都不會被關閉,且網絡也一直處于連接狀態。當前主流的移動平臺(iOS、Android、Windows Phone 8)都有監測非活動應用并自動將其關閉的功能,這意味著在移動平臺上我們要上傳一個大文件時更容易遇到中途程序突然被關閉的情況,斷點續傳也就更有價值。
支持斷點續傳功能之后,在客戶端很自然可以支持一個新功能:暫停或恢復某個文傳的上傳過程。
## 上傳后續動作
我們曾在[上傳模型](http://developer.qiniu.com/docs/v6/api/overview/up/upload-models.html "上傳模型")中提過,在上傳時開發者可以指定上傳完成后服務端的后續動作,比如回調、自定義返回內容、303重定向等。可設置的后續動作與[表單上傳](http://developer.qiniu.com/docs/v6/api/overview/up/form-upload.html "表單上傳")中完全一致。
這里需要明確的是,雖然后續動作在生成[上傳憑證](http://developer.qiniu.com/docs/v6/api/reference/security/upload-token.html "上傳憑證")時已經指定,但這些后續動作只在服務端處理完mkfile請求后才會發生,而且也只有mkfile請求的內容可以包含[變量](http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html "變量")。
## 在線示例
[在線斷點繼上傳示例](http://jsfiddle.net/gh/get/extjs/4.2/icattlecoder/jsfiddle/tree/master/resumbleupload)