在無線網路下,上傳比較大的檔案期間長,可能會遇到因為網路條件差、使用者切換網路等原因導致上傳中途失敗,整個檔案需要重新上傳。為此,iOS SDK提供了斷點續傳上傳功能。
背景資訊
對於移動端而言,如果不是大檔案(例如小於5 GB的檔案),不建議使用斷點續傳的方式上傳。斷點續傳上傳是通過分區上傳實現的,上傳單個檔案需要進行多次網路請求,效率不高。對於通過斷點續傳的方式上傳大於5 GB的檔案時:
斷點續傳上傳前
通過斷點續傳上傳的方式將檔案上傳到OSS前,您可以指定斷點記錄的儲存檔案夾。斷點續傳上傳僅在本次上傳生效。
如果未指定斷點記錄的儲存檔案夾,假設某個分區因為網路原因等導致檔案上傳失敗時,將耗用大量的重試時間及流量來重新上傳整個大檔案。
如果指定了斷點記錄的儲存檔案夾,在檔案上傳失敗時,將從斷點記錄處繼續上傳未上傳完成的部分。
斷點續傳上傳時
斷點續傳上傳僅支援上傳本地檔案。斷點續傳上傳支援上傳回調,使用方法與常見的上傳回調類似。具體操作,請參見Callback。
斷點續傳上傳依賴InitMultipartUpload、UploadPart、ListParts、CompleteMultipartUpload、AbortMultipartUpload等介面來實現。如果您需要通過STS鑒權模式來使用斷點續傳上傳,則需要保證您擁有訪問以上API介面的許可權。
斷點續傳上傳預設已開啟每個分區上傳時的MD5校正,因此無需在請求中設定
Content-Md5
頭部。如果同一任務一直得不到續傳,可能會在OSS上積累無用片段。此時,您可以為Bucket設定lifeCycle規則的方式來定時清理片段,詳情請參見生命週期管理。
重要出於片段管理的原因,如果在斷點續傳時取消當前上傳任務,預設會同步清理已經上傳到伺服器的分區。取消上傳任務時如果仍希望保留斷點上傳記錄,則需要指定斷點記錄的儲存檔案夾並修改deleteUploadIdOnCancelling參數。如果服務端保留記錄時間過長,且Bucket已設定lifeCycle規則定時清理了服務端分區,會出現服務端和移動端記錄不一致的問題。
注意事項
使用本文樣本前您需要先通過自訂網域名、STS等方式建立OSSClient,具體請參見初始化。
說明所建立儲存空間的所屬地區取決於初始化配置的endpoint地區資訊。
要上傳檔案,您必須有
oss:PutObject
許可權。具體操作,請參見為RAM使用者授權自訂的權限原則。
範例程式碼
斷點記錄在本地持久儲存時,調用
resumableUpload
方法實現斷點續傳上傳的過程如下:OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new]; resumableUpload.bucketName = OSS_BUCKET_PRIVATE; //... NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; resumableUpload.recordDirectoryPath = cachesDir;
說明使用斷點續傳上傳檔案失敗時會產生斷點記錄檔案,然後從斷點記錄處繼續上傳直到上傳完成。上傳成功後會自動刪除斷點記錄檔案,預設情況下不會在本地持久儲存斷點記錄。
斷點續傳上傳的完整範例程式碼如下:
// 擷取UploadId上傳檔案。 OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new]; resumableUpload.bucketName = <bucketName>; // objectKey等同於objectName,表示斷點上傳檔案到OSS時需要指定包含檔案尾碼在內的完整路徑,例如abc/efg/123.jpg resumableUpload.objectKey = <objectKey>; resumableUpload.partSize = 1024 * 1024; resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend); }; NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; // 設定斷點記錄儲存路徑。 resumableUpload.recordDirectoryPath = cachesDir; // 將參數deleteUploadIdOnCancelling設定為NO,表示不刪除斷點記錄檔案,上傳失敗後將從斷點記錄處繼續上傳直到檔案上傳完成。如果不設定此參數,即保留預設值YES,表示刪除斷點記錄檔案,下次再上傳同一檔案時則重新上傳。 resumableUpload.deleteUploadIdOnCancelling = NO; resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>]; OSSTask * resumeTask = [client resumableUpload:resumableUpload]; [resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 此任務無法續傳,需擷取新的uploadId重新上傳。 } } else { NSLog(@"Upload file success"); } return nil; }]; // [resumeTask waitUntilFinished]; // [resumableUpload cancel];