主要是需要注意,在客服端发请求给服务器的时候,在请求头里是可以设置服务器返回的数据从哪开始,到哪结束的.

当服务器响应客户端时,是可以拿到服务器返回数据具体类型以及大小的

思路:

在接收到服务器响应时,创建一个空文件,和一个跟空文件相关联的句柄对象

然后,在接收到服务器返回的数据时,利用句柄对象,移动到文件末尾,将数据拼接到文件末尾

在接受完服务器返回的数据后,关闭句柄

#import <Foundation/Foundation.h>

@interface ZYFileDownLoad : NSObject
//所需要下载文件的远程URL(连接服务器的路径)
@property (nonatomic, strong) NSString *urlStr; //文件的存储路径
@property (nonatomic, strong) NSString *goalPath; //是否正在下载
@property (nonatomic, readonly, getter= isDownLoading) BOOL downLoading; //监听下载进度
@property (nonatomic, copy) void (^progressHandler)(double progress); //下载完成后的回调
@property (nonatomic, copy) void (^finishHandler)(); //下载失败后的回调
@property (nonatomic, copy) void (^failureHandler)(NSError *error); //开始下载
- (void)start; //暂停下载
- (void)pause; @end /*
文件一般保存在下面的地址,Documents路径下的文件需要同步,文件大的话消耗性能,tmp路径下随时会被删除
所以一般保存在Library\Caches路径下 获取此路径:
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [caches stringByAppendingPathComponent:@"文件名.后缀名"];
*/
#import "ZYFileDownLoad.h" @interface ZYFileDownLoad() <NSURLConnectionDataDelegate>
//当前已下载的数据长度
@property (nonatomic, assign) long long currentLength; //连接对象
@property (nonatomic, strong) NSURLConnection *connection; //总的文件长度
@property (nonatomic, assign) long long totalLength; //写入文件句柄
@property (nonatomic, strong) NSFileHandle *writeHandle; @end @implementation ZYFileDownLoad
- (void)start
{
[self.urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:self.urlStr]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; //设置请求头信息,这里表示,此次数据范围是currentProgress 到文件最后(也就是只设置开头从什么地方下载)
NSString *value = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];
[request setValue:value forHTTPHeaderField:@"Range"]; self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; _downLoading = YES;
} - (void)pause
{
[self.connection cancel];
self.connection = nil;
_downLoading = NO;
} #pragma mark ----NSURLConnectionDataDelegate //请求错误(失败)的时候调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if (self.failureHandler) {
self.failureHandler(error);
}
} - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (self.totalLength) return; //当已经回复过响应了,就无需再次回复(主要用于暂停下载,再回复下载操作) //创建一个空的文件到沙盒中
NSFileManager *manager = [NSFileManager defaultManager];
[manager createFileAtPath:self.goalPath contents:nil attributes:nil]; ////创建写数据的文件句柄
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.goalPath]; //获得完整文件的长度(服务器响应客户端时,会返回具体具体的文件长度)
self.totalLength = response.expectedContentLength;
} //当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
self.currentLength += [data length]; //下载完成,累加长度 //进度
double progress = (double)self.currentLength / self.totalLength; //通过block回调,可以执行block里面的操作
if (self.progressHandler) {
self.progressHandler(progress);
} //移动文件尾部,往尾部追加数据
[self.writeHandle seekToEndOfFile];
[self.writeHandle writeData:data];
} - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//下载完毕,请客属性
self.currentLength = 0;
self.totalLength = 0; if (self.currentLength == self.totalLength) {
//下载完毕,关闭连接
[self.writeHandle closeFile];
self.writeHandle = nil;
} if (self.finishHandler) {
self.finishHandler();
}
}
@end

iOS中大文件下载(单线程下载)的更多相关文章

  1. 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】

    一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...

  2. ios的网络数据下载和json解析

    ios的网络数据下载和json解析 简介 在本文中,笔者将要给大家介绍如何使用nsurlconnection 从网上下载数据,以及解析json数据格式,以及如何显示数据和图片的异步下载显示. 涉及的知 ...

  3. IOS开发-第三方SDWebImage下载网络图片的使用

    从网络上请求图片时,没有使用第三方的话,下载会很慢,而且堵塞线程,还要自己处理多线程问题,效果还非常不明显,使用了SDWebImage这个第三方类库之后,下载图片就变的容易多了. SDWebImage ...

  4. ios背景更新和下载

    ios背景更新和下载 by 吴雪莹 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NS ...

  5. iOS之网络数据下载和JSON解析

    iOS之网络数据下载和JSON解析 简介 在本文中笔者将要给大家介绍IOS中如何利用NSURLconnection从网络上下载数据以及如何解析下载下来的JSON数据格式,以及如何显示数据和托图片的异步 ...

  6. vue打包app嵌入h5,区分app进入和android,ios显示不同的下载链接

    vue打包app嵌入h5,区分app进入和android,ios显示不同的下载链接 需求:自己app打开的登录页面不显示app下载链接.其他地方打开判断android手机的跳转到android下载页链 ...

  7. xkcd 单线程下载图片

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  8. urlretrieve 如何给文件下载设置下载进度?

    #python #xiaodeng #如何给文件下载设置下载进度? import urllib def callbackinfo(down,block,size): ''' 回调函数: down:已经 ...

  9. iOS 开发工具网页下载

    iOS 开发工具网页下载地址: https://developer.apple.com/downloads/

随机推荐

  1. 【Linux】字符转换命令paste

    这个 paste 就要比join 简单多了!相对于 join 必须要比对两个文件的数据相关性, paste 就直接『将两行贴在一起,且中间以 [tab] 键隔开』而已!简单的使用方法: [root@w ...

  2. Java中类的设计技巧

    1)  一定要将数据设计为私有: 不要破坏封装性.有时需要编写一个访问器或更改器方法,但是最好还是保持实例域的私有性.数据的表示形式可能会改变,但他们的使用方式却不会经常发生变化.当数据保持私有时,他 ...

  3. MongoDB学习笔记(6)--find

    MongoDB 查询文档 MongoDB 查询文档使用 find() 方法. find() 方法以非结构化的方式来显示所有文档. 语法 MongoDB 查询数据的语法格式如下: db.collecti ...

  4. 利用css如何让嵌套的div层不继承父div层的透明度?

    http://zhidao.baidu.com/link?url=cvQhh0Q7_ah0qg9tc-2zP0cjB_PoIiIq6t6RFpp4aZPPNoVJUqyy7TT41TU5pWzRtRY ...

  5. “C++的数组不支持多态”?

    先是在微博上看到了个微博和云风的评论,然后我回了“楼主对C的内存管理不了解”. 后来引发了很多人的讨论,大量的人又借机来黑C++,比如: //@Baidu-ThursdayWang:这不就c++弱爆了 ...

  6. poj3041(最小顶点覆盖)

    链接:点击打开链接 题意:N*N的矩阵中有一些点代表陨石.每次仅仅能消灭一行或一列连,问须要多少次才干所有消灭 代码: #include <map> #include <queue& ...

  7. Java 内存溢出思维导图

    文 by / 林本托 Tips 做一个终身学习的人. 在 Java 内存中,只有一个区域不会发生 OOM 异常,那就是程序计数器内存.下面的思维导图记录了每个内存区域发生内存异常的条件和基本的解决思路 ...

  8. 《KAFKA官方文档》入门指南(转)

    1.入门指南 1.1简介 Apache的Kafka™是一个分布式流平台(a distributed streaming platform).这到底意味着什么? 我们认为,一个流处理平台应该具有三个关键 ...

  9. Android Logcat信息级别解读

    Android Logcat信息级别解读 Logcat信息分为好几个级别,分别是:Assert(断言).Debug(调试).Error(错误).Info(信息).Verbose(详细).Warning ...

  10. 如何上传代码到github?

    如何上传代码到github? 首先你需要一个github账号,所有还没有的话先去注册吧! https://github.com/ 我们使用git需要先安装git工具,这里给出下载地址,下载后一路直接安 ...