對下載文件進行處理,每下載一點數(shù)據(jù),就將數(shù)據(jù)寫到磁盤中(通常是沙盒中),避免在內(nèi)存累積數(shù)據(jù)(NSURLConnection下載)
當下載任務終止時,記錄任務終止時的位置信息,以便下次開始繼續(xù)下載
使用NSFileHandle類實現(xiàn)寫數(shù)據(jù)的下載步驟(完整核心代碼)
設(shè)置相關(guān)成員屬性
/**所要下載文件的總長度*/@PRoperty (nonatomic, assign) NSInteger contentLength;/**已下載文件的總長度*/@property (nonatomic, assign) NSInteger currentLength/**文件句柄,用來實現(xiàn)文件存儲*/@property (nonatomic, strong) NSFileHandle *handle;創(chuàng)建、發(fā)送請求
// 1. 創(chuàng)建請求路徑NSURL *url = [NSURL URLWithString:@"此處為URL字符串"];// 2. 將URL封裝成請求NSURLRequest *request = [NSURLRequest requestWithURL:url];// 3. 通過NSURLConnection,并設(shè)置代理[NSURLConnection connectionWithRequest:request delegate:self];遵守代理協(xié)議NSURLConnectionDataDelegate,實現(xiàn)代理方法
/*** 接收到服務器響應時調(diào)用的方法*/- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response{ //獲取所要下載文件的總長度 self.contentLength = [response.allHeaderFields[@"Content-Length"] integerValue]; //拼接一個沙盒中的文件路徑 NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"minion_15.mp4"]; //創(chuàng)建指定路徑的文件 [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]; //創(chuàng)建文件句柄 self.handle = [NSFileHandle fileHandleForWritingAtPath:filePath];}/*** 接收到服務器的數(shù)據(jù)時調(diào)用的方法*/- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //定位到文件尾部,將服務器每次返回的文件數(shù)據(jù)都拼接到文件尾部 [self.handle seekToEndOfFile]; //通過文件句柄,將文件寫入到沙盒中 [self.handle writeData:data]; //拼接已下載文件總長度 self.currentLength += data.length; //計算下載進度 CGFloat progress = 1.0 * self.currentLength / self.contentLength;}/*** 文件下載完畢時調(diào)用的方法*/- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ //關(guān)閉文件句柄,并清除 [self.handle closeFile]; self.handle = nil; //清空已下載文件長度 self.currentLength = 0;}使用NSOutputStream類實現(xiàn)寫數(shù)據(jù)的下載步驟(部分代碼,其他部分代碼同上)
設(shè)置NSOutputStream成員屬性
@property (nonatomic, strong) NSOutputStream *stream;初始化NSOutputStream對象,打開輸出流
/**接收到服務器響應的時候調(diào)用*/- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ //獲取下載數(shù)據(jù)保存的路徑 NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *filePath = [cache stringByAppendingPathComponent:response.suggestedFilename]; //利用NSOutputStream往filePath文件中寫數(shù)據(jù),若append參數(shù)為yes,則會寫到文件尾部 self.stream = [[NSOutputStream alloc] initToFileAtPath:filePath append:YES]; //打開數(shù)據(jù)流 [self.stream open];}寫文件數(shù)據(jù)
/**接收到數(shù)據(jù)的時候調(diào)用*/- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [self.stream write:[data bytes] maxLength:data.length];}關(guān)閉輸出流
/**數(shù)據(jù)下載完畢的時候調(diào)用*/- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ [self.stream close];}詳細的下載步驟
設(shè)置下載任務task的為成員變量
@property (nonatomic, strong) NSURLSessionDownloadTask *task;獲取NSURLSession對象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];初始化下載任務任務
self.task = [session downloadTaskWithURL:(此處為下載文件路徑URL)];實現(xiàn)代理方法
/**每當寫入數(shù)據(jù)到臨時文件的時候,就會調(diào)用一次該方法,通常在該方法中獲取下載進度*/- (void)URLSession:(NSURLSession *)session downloadTask: (NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ // 計算下載進度 CGFloat progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite;}/**任務終止時調(diào)用的方法,通常用于斷點下載*/- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{ //fileOffset:下載任務中止時的偏移量}/**遇到錯誤的時候調(diào)用,error參數(shù)只能傳遞客戶端的錯誤*/- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ }/**下載完成的時候調(diào)用,需要將文件剪切到可以長期保存的文件夾中*/- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ //生成文件長期保存的路徑 NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename]; //獲取文件句柄 NSFileManager *fileManager = [NSFileManager defaultManager]; //通過文件句柄,將文件剪切到文件長期保存的路徑 [fileManager moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];}操作任務狀態(tài)
/**開始/繼續(xù)下載任務*/[self.task resume];/**暫停下載任務*/[self.task suspend];新聞熱點
疑難解答