今天須要用AFNetworking實現斷點續傳的功能,可是在進行了一番研究以後,發現AFNetworking雖然支持下載文件的暫停和繼續,可是程序從新啓動後再次下載沒法進行續傳。網上有說能夠經過AFDownloadRequestOperation這個AFNetworking的擴展庫來實現從新啓動後的續傳,可是通過本人測試,這個庫在最新的AFNetworking上會報錯,無奈之下,參考他的代碼,本身實現了一個,在這裏分享給你們。html
實現的代碼以下:緩存
01.
//獲取已下載的文件大小
02.
- (unsigned
long
long
)fileSizeForPath:(NSString *)path {
03.
signed
long
long
fileSize =
0
;
04.
NSFileManager *fileManager = [NSFileManager
new
];
// default is not thread safe
05.
if
([fileManager fileExistsAtPath:path]) {
06.
NSError *error = nil;
07.
NSDictionary *fileDict = [fileManager attributesOfItemAtPath:path error:&error];
08.
if
(!error && fileDict) {
09.
fileSize = [fileDict fileSize];
10.
}
11.
}
12.
return
fileSize;
13.
}
14.
//開始下載
15.
- (
void
)startDownload {
16.
NSString *downloadUrl = @
"http://www.xxx.com/xxx.zip"
;
17.
NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:
0
];
18.
NSString *downloadPath = [cacheDirectory stringByAppendingPathComponent:@
"xxx.zip"
];
19.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadUrl]];
20.
//檢查文件是否已經下載了一部分
21.
unsigned
long
long
downloadedBytes =
0
;
22.
if
([[NSFileManager defaultManager] fileExistsAtPath:downloadPath]) {
23.
//獲取已下載的文件長度
24.
downloadedBytes = [self fileSizeForPath:downloadPath];
25.
if
(downloadedBytes >
0
) {
26.
NSMutableURLRequest *mutableURLRequest = [request mutableCopy];
27.
NSString *requestRange = [NSString stringWithFormat:@
"bytes=%llu-"
, downloadedBytes];
28.
[mutableURLRequest setValue:requestRange forHTTPHeaderField:@
"Range"
];
29.
request = mutableURLRequest;
30.
}
31.
}
32.
//不使用緩存,避免斷點續傳出現問題
33.
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];
34.
//下載請求
35.
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
36.
//下載路徑
37.
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:downloadPath append:YES];
38.
//下載進度回調
39.
[operation setDownloadProgressBlock:^(NSUInteger bytesRead,
long
long
totalBytesRead,
long
long
totalBytesExpectedToRead) {
40.
//下載進度
41.
float
progress = ((
float
)totalBytesRead + downloadedBytes) / (totalBytesExpectedToRead + downloadedBytes);
42.
}];
43.
//成功和失敗回調
44.
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
45.
46.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
47.
48.
}];
49.
[operation start];
50.
}
須要注意的是,此種寫法僅適用於下載zip包,由於下載其餘格式的文件有可能出現數據過多的狀況。當文件已經下載完成時,再次調用該函數,沒法判斷文件是否已經下載完整,因而會再次下載,此時服務器會報416錯,同時返回也會輸出到文件中,使得文件大小異常。可是zip格式不受影響。服務器
轉自:http://www.it165.net/pro/html/201403/10755.htmlapp