网络文件下载

- NSURLConnection- 开发简单的网络请求还是比较方便,可以利用异步方法问题: 1. 没有下载进度,会影响用户体验 2. 有内存峰值!下载的文件有多大,NSData就会占用多大的内存! [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)- 开发复杂的网络请求,例如:大文件下载,仍然需要使用代理来开发,非常繁琐!遵守协议// 1. 接收到服务器的响应 - 状态行&响应头 - 做一些准备工作- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response// 2. 接收到服务器的数据 - 此代理方法可能会执行多次,因为会接收到多个 data- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data// 3. 所有数据加载完成 - 所有数据都传输完毕之后被调用!只是最后一个通知!- (void)connectionDidFinishLoading:(NSURLConnection *)connection// 4. 下载失败或者错误,提示:在正常的商业应用开发中一定要做出错处理!- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error- 数据流/** 保存文件的输出流 - (void)open; 写入之前,打开流 - (void)close; 完成之后,关闭流 */@property (nonatomic, strong) NSOutputStream *fileStrem; // 以追加的方式打开文件流 self.fileStrem = [[NSOutputStream alloc] initToFileAtPath:self.tartgetFilePath append:YES]; [self.fileStrem open]; // 将数据追加到文件流中 [self.fileStrem write:data.bytes maxLength:data.length]; // 关闭文件流 [self.fileStrem close];文件管理- NSFileManager NSFileManager: 主要功能,创建目录,检查目录是否存在,遍历目录,删除文件...针对文件级的操作,类似于 Finder // 删除文件,removeItemAtPath 如果文件存在,就会直接删除,如果文件不存在,就什么也不做,也不会抱错! [[NSFileManager defaultManager] removeItemAtPath:self.tartgetFilePath error:NULL];- NSFileHandle NSFileHandle: 文件"句柄(文件指针)",如果在开发中,看到 Handle 这个单词,就意味着是对前面的单词"File"进行操作的对象 // 注意:如果文件不存在,fp 在实例化的结果是空 NSFileHandle *fp = [NSFileHandle fileHandleForWritingAtPath:self.tartgetFilePath]; // 有个坑(陷阱),容易写错方法 // 1. 将文件指针移动到文件的末尾 [fp seekToEndOfFile]; // 2. 写入文件 [fp writeData:data]; // 3. 关闭文件,在 C 语言的开发中,凡事涉及到文件读写,打开和关闭通常是成对出现的 [fp closeFile];- 运行循环/** 下载线程的运行循环 */@property (nonatomic, assign) CFRunLoopRef downloadRunloop; 将下载操作放到异步去执行 // 1. 拿到当前线程的运行循环 self.downloadRunloop = CFRunLoopGetCurrent(); // 2. 启动运行循环 CFRunLoopRun(); // 3. 停止下载线程所在的运行循环 CFRunLoopStop(self.downloadRunloop);/** 同步方法的应用场景 1. 抓取互联网络上的数据,如果开多个线程异步抓取,很容易被禁掉 ip 2. 加载本地文件,可以直接使用同步方法,会更加简单 3. *** 加载要下载文件的头部信息,HEAD 方法 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];NSURLSession- 用来简单的下载,解压缩 // 获取单例sesson NSURLSession *sesson = [NSURLSession sharedSession]; // 发起会话任务 [[sesson dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // 反序列化 id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; NSLog(@"%@",result); }] resume]; // 记住,默认会话是挂起的,需要要resume一下- 使用代理方法监听下载状态/** 全局的网络会话,管理所有的网络任务 */@property (nonatomic, strong) NSURLSession *session;if (_session == nil) { // config 提供了一个全局的网络环境配置,包括:身份验证,浏览器类型,cookie,缓存,超时时长... // 一旦设置可以全局共享,替代 NSURLRequest 中的附加信息! NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];} /** 如果要跟进下载进度,不能使用块代码回调的方式! */ // 如果要使用监听,设置代理,就不能使用体统的全局session单例,需要设置自己的session- 开始下载 [[self.session downloadTaskWithURL:url] resume];- #pragma mark 代理方法// 断点续传- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{}// 下载进度- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ float progress = (float)totalBytesWritten / totalBytesExpectedToWrite; NSLog(@"%f======>",progress);}- 取消会话- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; // 取消会话 [self.session invalidateAndCancel]; self.session = nil;}// 下载成功- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSLog(@"下载成功"); // 完成任务,如果会话已经被设置成完成,就无法再次使用! [self.session finishTasksAndInvalidate]; self.session = nil;}/** 取消会话的位置? 1> 下载完成 // 完成任务,如果会话已经被设置成完成,就无法再次使用! // Attempted to create a task in a session that has been invalidated [self.session finishTasksAndInvalidate]; // 清空session self.session = nil; 2> 视图控制器销毁前 [self.session invalidateAndCancel]; self.session = nil; *** 两种方式的对比 1. 可以保证文件"可能"完整被下载完 这种方法会重复创建和销毁 session,会造成额外的开销 2. 只是在离开界面前,销毁session,相对开销会小 缺点:如果一个文件没有下载完成,会直接被取消掉! 真正的解决方法! - 在网络访问中,应该将所有的网路访问操作,封装到一个方法中!由一个统一的"单例"来负责处理所有的网络事件! - Session对代理(单例)进行强引用!单例本身就是一个静态实例,本身就不需要被释放! - AFN -> 需要建立一个 AFN 管理器的单例!统一负责所有的网络事件处理! */- 暂停下载 // 应该只能够暂停一次 [self.downloadTask cancelByProducingResumeData:^(NSData *resumeData) { // 应该保存数据 self.resumeData = resumeData; // 释放下载任务 self.downloadTask = nil; }];- 继续下载 // 先判断是否有数据 if (self.resumeData == nil) { NSLog(@"当前没有下载任务"); return; } // 所有下载任务都是有session发起的 self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData]; self.resumeData = nil; [self.downloadTask resume];解压缩SSZipArchive.h框架,需要导入动态库libz.dylib
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值