文件下载(断点续传)——dataTask
2016-07-07 16:30
295 查看
<pre name="code" class="objc">// 文件的存放路径(caches) #define FilePath [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"test.mp4"] // 文件的已下载长度 #define DownloadLength [[[NSFileManager defaultManager] attributesOfItemAtPath:FilePath error:nil][NSFileSize] integerValue] #import "ViewController.h" @interface ViewController () <NSURLSessionDataDelegate> /** 下载任务 */ @property (nonatomic, strong) NSURLSessionDataTask *task; /** session */ @property (nonatomic, strong) NSURLSession *session; /** 写文件的流对象 */ @property (nonatomic, strong) NSOutputStream *stream; /** 文件的总长度 */ @property (nonatomic, assign) NSInteger totalLength; @end @implementation ViewController - (NSURLSession *)session { if (!_session) { _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]]; } return _session; } - (NSOutputStream *)stream { if (!_stream) { _stream = [NSOutputStream outputStreamToFileAtPath:FilePath append:YES]; } return _stream; } /** * 开始下载 */ - (IBAction)start:(id)sender { // 创建请求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]]; // 断点续传的本质是根据之前下载的进度,设置请求头。告诉服务器从哪里继续下载 // Range : bytes=0-1024 表示从第0个字节下载1024个字节 bytes=2048-表示从第2048个字节下载完 // 设置请求头 NSString *range = [NSString stringWithFormat:@"bytes=%zd-", DownloadLength]; [request setValue:range forHTTPHeaderField:@"Range"]; // 创建一个Data任务 // 不用downloadTask 是因为downloadTask默认把下载的文件保存在temp文件中,应用一死就被清理掉了 self.task = [self.session dataTaskWithRequest:request]; // 启动任务 [self.task resume]; } /** * 暂停下载 */ - (IBAction)pause:(id)sender { [self.task suspend]; } /** * 继续下载 */ - (IBAction)goOn:(id)sender { [self.task resume]; } #pragma mark - <NSURLSessionDataDelegate> /** * 1.接收到响应 */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler { // 打开流 [self.stream open]; // 获得服务器这次请求 返回数据的总长度 @"Content-Length"固定key,不能写错 self.totalLength = [response.allHeaderFields[@"Content-Length"] integerValue] + DownloadLength; // 接收这个请求,允许接收服务器的数据 completionHandler(NSURLSessionResponseAllow); } /** * 2.接收到服务器返回的数据(这个方法可能会被调用N次) */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { // 写入数据 [self.stream write:data.bytes maxLength:data.length]; // 下载进度 NSLog(@"%f", 1.0 * DownloadLength / self.totalLength); } /** * 3.请求完毕(成功\失败) */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { // 关闭流 [self.stream close]; self.stream = nil; } @end
相关文章推荐
- [暑假集训] jzoj 2016.7.7 noip模拟赛C 总结
- XSS 简单理解
- lintcode:交换链表当中两个节点
- hdu 2594 Simpsons’ Hidden Talents
- 简单Windows控制台贪吃蛇(二维数组模拟地图, 链表模拟贪吃蛇, WASD控制行走, gotoxy替换刷新操作)
- 三消
- 输入一个整数和一棵二元树,打印出所有和为该整数的二元树中的路径
- DWR3实现服务器端向客户端精确推送消息
- 报道一日记
- 无线通讯LoRa---SX1278芯片开发笔记
- maven报错非法字符:\65279 错误
- 走着走着就散了--徐志摩
- 美团在Redis上踩过的一些坑-目录(本人非美团)(转)
- JAVA JLabel自定义子类无法显示
- 在cmd模式下对mysql的操作语句
- javaScript 数组遍历方法总结
- oracle分析函数:二、秩运算(DENSE_RANK函数,RANK函数)
- 矩阵中的路径
- struts2--知识点
- Linux下学习DB2命令的笔记