IOS 斷點續傳原理淺析

本文轉自:http://www.jianshu.com/p/de263da8cdb0

斷點續傳概述:

斷點續傳就是從文件上次中斷的地方開始重新下載或上傳數據,當下載大文件的時候,如果沒有實現斷點續傳功能,那麼每次出現異常或者用戶主動的暫停,都會去重頭下載,這樣很浪費時間。所以斷點續傳的功能就應運而生了


在說IOS斷點續傳之前,下面來簡單介紹 HTTP 斷點續傳的原理

其實斷點續傳的原理很簡單,就是在Http的請求上和一般的下載有所不同而已,舉個例子吧!

1.瀏覽器請求服務器上的一個文件名爲test.zip時,請求內容只展示了一些與本文有關的信息

GET /test.zip HTTP/1.1
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

2.服務器收到請求後,按要求尋找請求的文件,提取文件的信息,然後返回給瀏覽器,返回信息如下:

200
Content-Length=66667777
Accept-Ranges=bytes
Content-Type=application/octet-stream

爲了實現從文件已經下載的地方開始繼續下載。所以在客戶端傳給服務器的時候要多加一條信息--從哪裏開始。下面是客戶端請求時的請求信息,要求從44445555字節開始。
1

GET /test.zip HTTP/1.0
User-Agent: NetFox
RANGE: bytes=44445555-

上面的請求信息多了一個新的字段RANGE RANGE:bytes=44445555-
這段話的意思就是告訴服務器test.zip這個文件從44445555字節開始傳,前面的字節不用傳了。服務器收到這個請求以後,返回的信息如下:

206
Content-Length=66667777
Content-Range=bytes 44445555-66667777
Content-Type=application/octet-stream

和第一次服務器返回的信息相比,增加了一行:
Content-Range=bytes 44445555-66667777
返回的代碼也改爲206了,而不再是200了。
知道了以上原理,就可以進行斷點續傳的編程了。

IOS斷點續傳原理
要實現斷點續傳 , 服務器必須支持(這個很重要,一個巴掌是拍不響的,如果服務器不支持,那麼客戶端寫的再好也沒用)

// 1 指定下載文件地址 URLString
 // 2 獲取保存的文件路徑 filePath
 // 3 創建 NSURLRequest
 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];
 unsigned long long downloadedBytes = 0;

 if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
 // 3.1 若之前下載過 , 則在 HTTP 請求頭部加入 Range
  // 獲取已下載文件的 size
  downloadedBytes = [self fileSizeForPath:filePath];

  // 驗證是否下載過文件
  if (downloadedBytes > 0) {
    // 若下載過 , 斷點續傳的時候修改 HTTP 頭部部分的 Range
    NSMutableURLRequest *mutableURLRequest = [request mutableCopy];
    NSString *requestRange =
    [NSString stringWithFormat:@"bytes=%llu-", downloadedBytes];
    [mutableURLRequest setValue:requestRange forHTTPHeaderField:@"Range"];
    request = mutableURLRequest;
  }
 }

 // 4 創建 AFHTTPRequestOperation
 AFHTTPRequestOperation *operation
 = [[AFHTTPRequestOperation alloc] initWithRequest:request];

 // 5 設置操作輸出流 , 保存在第 2 步的文件中
 operation.outputStream = [NSOutputStream
 outputStreamToFileAtPath:filePath append:YES];

 // 6 設置下載進度處理 block
 [operation setDownloadProgressBlock:^(NSUInteger bytesRead,
 long long totalBytesRead, long long totalBytesExpectedToRead) {
 // bytesRead 當前讀取的字節數
 // totalBytesRead 讀取的總字節數 , 包含斷點續傳之前的
 // totalBytesExpectedToRead 文件總大小
 }];

 // 7 設置 success 和 failure 處理 block
 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation
 *operation, id responseObject) {

 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

 }];

 // 8 啓動 operation
 [operation start];

使用以上代碼 , 斷點續傳功能就實現了

總結:

斷點續傳主要依賴於 HTTP 頭部定義的 Range 來完成。有了 Range,應用可以通過 HTTP 請求獲取失敗的資源,從而來恢復下載該資源。當然並不是所有的服務器都支持 Range,但大多數服務器是可以的。Range 是以字節計算的,請求的時候不必給出結尾字節數,因爲請求方並不一定知道資源的大小。
今天只是簡單的介紹了一下,關於斷點續傳其實不止這點知識!下次有時間的話繼續寫,希望各位多多提些意見!多謝!




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章