iOS网络-04-大文件下载
大文件下载注意事项
- 若不对下载的文件进行转存,会造成内存消耗急剧升高,甚至耗尽内存资源,造成程序终止。
- 在文件下载过程中通常会出现中途停止的状况,若不做处理,就要重新开始下载,浪费流量。
大文件下载的解决方案
- 对下载文件进行处理,每下载一点数据,就将数据写到磁盘中(通常是沙盒中),避免在内存累积数据(NSURLConnection下载)
- 使用NSFileHandle类实现写数据
- 使用NSOutputStream类实现写数据
- 当下载任务终止时,记录任务终止时的位置信息,以便下次开始继续下载
大文件下载(NSURLConnection)
- 未支持断点下载
- 使用NSURLConnection的代理方式下载文件
- 在下载任务的不同阶段回调的代理方法中,完成转移下载文件,及记录终止位置的任务
- 使用NSFileHandle类实现写数据的下载步骤(
完整核心代码)设置相关成员属性
/**所要下载文件的总长度*/
@property (nonatomic, assign) NSInteger contentLength;
/**已下载文件的总长度*/
@property (nonatomic, assign) NSInteger currentLength
/**文件句柄,用来实现文件存储*/
@property (nonatomic, strong) NSFileHandle *handle;
创建、发送请求
// 1. 创建请求路径
NSURL *url = [NSURL URLWithString:@"此处为URL字符串"];
// 2. 将URL封装成请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3. 通过NSURLConnection,并设置代理
[NSURLConnection connectionWithRequest:request delegate:self];
遵守代理协议NSURLConnectionDataDelegate,实现代理方法
/**
* 接收到服务器响应时调用的方法
*/
- (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"];
//创建指定路径的文件
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
//创建文件句柄
self.handle = [NSFileHandle fileHandleForWritingAtPath:filePath];
}
/**
* 接收到服务器的数据时调用的方法
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//定位到文件尾部,将服务器每次返回的文件数据都拼接到文件尾部
[self.handle seekToEndOfFile];
//通过文件句柄,将文件写入到沙盒中
[self.handle writeData:data];
//拼接已下载文件总长度
self.currentLength += data.length;
//计算下载进度
CGFloat progress = 1.0 * self.currentLength / self.contentLength;
}
/**
* 文件下载完毕时调用的方法
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//关闭文件句柄,并清除
[self.handle closeFile];
self.handle = nil;
//清空已下载文件长度
self.currentLength = 0;
}
- 使用NSOutputStream类实现写数据的下载步骤(
部分代码,其他部分代码同上)设置NSOutputStream成员属性
@property (nonatomic, strong) NSOutputStream *stream;
初始化NSOutputStream对象,打开输出流
/**接收到服务器响应的时候调用*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//获取下载数据保存的路径
NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [cache stringByAppendingPathComponent:response.suggestedFilename];
//利用NSOutputStream往filePath文件中写数据,若append参数为yes,则会写到文件尾部
self.stream = [[NSOutputStream alloc] initToFileAtPath:filePath append:YES];
//打开数据流
[self.stream open];
}
写文件数据
/**接收到数据的时候调用*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.stream write:[data bytes] maxLength:data.length];
}
关闭输出流
/**数据下载完毕的时候调用*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self.stream close];
}
大文件下载(NSURLSession)
- 支持断点下载,自动记录停止下载时断点的位置
- 遵守NSURLSessionDownloadDelegate协议
- 使用NSURLSession下载大文件,被下载文件会被自动写入沙盒的临时文件夹tmp中
- 下载完毕,通常需要将已下载文件移动其他位置(tmp文件夹中的数据被定时删除),通常是cache文件夹中
- 详细的下载步骤
设置下载任务task的为成员变量
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
获取NSURLSession对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
初始化下载任务任务
self.task = [session downloadTaskWithURL:(此处为下载文件路径URL)];
实现代理方法
/**每当写入数据到临时文件的时候,就会调用一次该方法,通常在该方法中获取下载进度*/
- (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;
} /**任务终止时调用的方法,通常用于断点下载*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
//fileOffset:下载任务中止时的偏移量
} /**遇到错误的时候调用,error参数只能传递客户端的错误*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{ } /**下载完成的时候调用,需要将文件剪切到可以长期保存的文件夹中*/
- (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];
}
操作任务状态
/**开始/继续下载任务*/
[self.task resume]; /**暂停下载任务*/
[self.task suspend];
iOS网络-04-大文件下载的更多相关文章
- IOS NSURLConnection(大文件下载)
NSURL:请求地址 NSURLRequest:一个NSURLRequest对象就代表一个请求,它包含的信息有 一个NSURL对象 请求方法.请求头.请求体 请求超时 … … NSMutableURL ...
- ios开发网络学习三:NSURLConnection小文件大文件下载
一:小文件下载 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDele ...
- iOS开发网络请求——大文件的多线程断点下载
iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...
- iOS开发之网络编程--小文件下载
文件下载方式: 如果下载的文件比较小,下载方式: 直接用NSData的 +(id)dataWithContentsOfURL:(NSURL*)url; 利用NSURLConnection发送一个HTT ...
- 网络编程---(数据请求+slider)将网络上的大文件下载到本地,并打印其进度
网络编程---将网络上的大文件下载到本地,并打印其进度. 点击"開始传输"button.将网络上的大文件先下载下来,下载完毕后,保存到本地. UI效果图例如以下: watermar ...
- ios网络 -- HTTP请求 and 文件下载/断点下载
一:请求 http://www.jianshu.com/p/8a90aa6bad6b 二:下载 iOS网络--『文件下载.断点下载』的实现(一):NSURLConnection http://www. ...
- iOS开发-大文件下载与断点下载思路
大文件下载方案一:利用NSURLConnection和它的代理方法,及NSFileHandle(iOS9后不建议使用)相关变量: @property (nonatomic,strong) NSFile ...
- iOS网络相关知识总结
iOS网络相关知识总结 1.关于请求NSURLRequest? 我们经常讲的GET/POST/PUT等请求是指我们要向服务器发出的NSMutableURLRequest的类型; 我们可以设置Reque ...
- MTNET 自用ios网络库开源
短短两天就在https://git.oschina.net/gangwang/MTNET这里收获15个星 github 5星, 值得收藏! MTNET 自用ios网络库开源, 自用很久了,在数歀上架的 ...
随机推荐
- Hibernate基础映射
在说Hibernate映射前,我们先来了解下对象关系映射 ORM.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现.这样开发人员就可以把对数据库的操作转化为对这些对象的操作.我们 ...
- HDU4550+贪心
/* 贪心 先挑出最小的Mm,然后在Mm左侧的按情况考虑,右侧的按顺序排列. */ #include<stdio.h> #include<string.h> #include& ...
- 转iOS中delegate、protocol的关系
iOS中delegate.protocol的关系 分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报 delegateiosprocotolc ...
- 受限玻尔兹曼机(RBM)学习笔记(六)对比散度算法
去年 6 月份写的博文<Yusuke Sugomori 的 C 语言 Deep Learning 程序解读>是囫囵吞枣地读完一个关于 DBN 算法的开源代码后的笔记,当时对其中涉及的算 ...
- HMM 自学教程(八)总结
本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在HMM 学习最佳范例,这是针对国外网站上一个 HMM 教程的翻译,作者功底很深,翻译得很精彩,且在 ...
- Direct3D11学习:(三)Direct3D11初始化
转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 做完一系列的准备工作之后,我们就正式进入Direct3D11的学习了.我们就从Direct3D11的初始化工作开 ...
- JAVA魔法堂:折腾Mybatis操作SQLite的SQLException:NYI异常
一.坑爹 在使用Mybatis3.2.7+sqlite-jdbc3.3时,在执行查询操作,不管returnType和parameterType传什么值均报位于mapper.xml文件中的java.sq ...
- IOS开发UI基础UITextView相关属性
UITextView相关属性 • text: 设置textView中文本_textView.text = @"Now is the time for all good develope ...
- 收集了50道基础的java面试题
下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...
- java 接口学习
你应该知道接口是一种契约,它与实现方式无关 但是类,即使是抽象类,你都能自定义成员变量,而成员变量往往就与实现方式有关. 这一点的实际意义不大. 但是有一点,类会暴露太多不必要,甚至不能暴露的东西,你 ...