* 移动客户端在和服务器交互的时候,上传和下载使用十分广泛。

* 在我们下载文件的时候,我们在点击暂停的时候可以暂停下载,点击下载的时候可以继续下载,这个功能如何实现?

* 下载进度条如何显示?

先大概叙述一下断点下载的原理:

* 首先先判断要判断要下载的文件在本地沙盒中是否存在。

* 如果存在的话,要判断下载文件的长度。

* 假设文件长度是500,我们发起下载请求的时候应该从500开始。

* 点击暂停下载,应该将链接断掉。

* 再次点击下载的时候,根据下载文件长度,继续下载。

下面与代码结合起来叙述具体的实现:

* 假设我们要下载的文件在服务器的路径为:http://localhost:8080:down/xcode_6.dmg;

* 我们将要下载的文件方法本地沙盒中。文件命名为:xcode.dmg.

* 获取文件保存路径的代码:(折叠)

 -(NSString *)getFilePath
{
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"xcode.dmg"];
return filePath;
}

下载文件保存路径

* 因为下载的文件比较大,我们需要采取异步请求网络。

* 异步请求网络常用的有四个代理方法。

* 发起网络请求下载。(下载起始点为上次暂停点,判断上次暂停位置方法是,获取文件属性,从属性中可以查看文件长度,请求点为该长度后面的内容)

* 假设向获取某个字节的内容,可以使用:

    //bytes = 0-499 请求前500个字节的内容

    //bytes = 500- 请求500字节之后的内容

    //bytes = 500-1000 请求资源中某一范围的内容

    //bytes = 0-1,499-500 请求多个范围之间的内容

* 进度条过去文件下载进度,可以使用已经下载的文件的字节数/文件的总字节数。

下面为具体的代码段,里面有详细的注释:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<NSURLConnectionDataDelegate>
{
//进度条变量,显示文件下载进度
IBOutlet UIProgressView *_progress;
//文件处理,将下载的文件写入本地沙盒
NSFileHandle *_fileHandle;
//url连接,点解暂停,取消连接,点击下载,开始下载
NSURLConnection *_connection;
//已经接收数据大小
long long _receiveSize;
//文件总共的大小
long long _totalSize;
} //下载按钮点击响应函数
- (IBAction)download:(id)sender;
//暂停按钮点击响应函数
- (IBAction)pause:(id)sender; @end
- (IBAction)download:(id)sender
{
//文件的路径
NSString *string = @"http://localhost:8080/down/xcode_6.dmg";
//文件的路径转化为url
NSURL *url = [NSURL URLWithString:string];
//创建可变请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//判断沙盒路径下有没有这个文件,YES表示这个文件已经下载,NO表示还没有下载
if ([[NSFileManager defaultManager] fileExistsAtPath:[self getFilePath]] == YES)
{ //根据文件的属性,获取之前下载数据量是多少
NSDictionary *fileDic = [[NSFileManager defaultManager]attributesOfItemAtPath:[self getFilePath] error:nil];
//文件的长度就是已经下载的数据量
_receiveSize = [fileDic[NSFileSize] longLongValue];
//设置Range,从Range之后的内容开始下载
//bytes = 0-499 请求前500个字节的内容
//bytes = 500- 请求500字节之后的内容
//bytes = 500-1000 请求资源中某一范围的内容
//bytes = 0-1,499-500 请求多个范围之间的内容
NSString *bytes = [NSString stringWithFormat:@"bytes=%lld-",_receiveSize];
[request setValue:bytes forHTTPHeaderField:@"Range"]; }
//发起异步请求,文件比较法,使用异步请求
_connection = [NSURLConnection connectionWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//分析响应头
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
//获取响应头,是一个字典
NSDictionary *responseHeader = httpResponse.allHeaderFields;
//接收文件总的大小等于已经下载的数据量,加上为下载的数据量
_totalSize = _receiveSize + [responseHeader[@"Content-Length"] longLongValue];
//创建文件管理类
NSFileManager *fileManager = [NSFileManager defaultManager];
//沙盒中不存在要下载的文件,就创建该文件
if ([fileManager fileExistsAtPath:[self getFilePath]] == NO)
{
[fileManager createFileAtPath:[self getFilePath] contents:nil attributes:nil];
}
//根据路径写入文件
_fileHandle = [NSFileHandle fileHandleForWritingAtPath:[self getFilePath]];
} - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//文件比较大的话,需要多次写入,写入的话,需要将光标定位到结尾
[_fileHandle seekToEndOfFile];
//将数据写入到文件
[_fileHandle writeData:data];
//最新接收到数据的大小等于文件中已有的数据,加上刚刚下载的数据量
_receiveSize = _receiveSize + data.length;
//计算进度
float jundu = (float)_receiveSize / _totalSize;
//使用进度条来表示进度
_progress.progress = jundu;
} - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//文件完成传输,关闭文件管理
[_fileHandle closeFile];
} - (IBAction)pause:(id)sender
{
//点击暂停,取消请求连接
[_connection cancel];
_connection = nil;
} -(NSString *)getFilePath
{
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"xcode.dmg"];
return filePath;
}

最新文章

  1. python for mysql
  2. poj3013 邻接表+优先队列+Dij
  3. Win7_关闭休眠文件hiberfil.sys
  4. Linux SHELL脚本
  5. php的异步框架
  6. Scala:(1)变量
  7. Zedboard甲诊opencv图像处理(二)
  8. C#整理6——数组的应用
  9. zabbix监控服务器部署
  10. 如何判断img标签是否有src属性
  11. 框架学习笔记之Mybatis(二)
  12. 上传代码到github
  13. Linux和Windows启动后台程序
  14. ssh 报错Host key verification failed 或Ubuntu connect to serve 失败
  15. java native方法及JNI实例 (转)
  16. JS控制文本框只能输入数字 \保留小数点后两位
  17. keras callback中的stop_training
  18. ubuntu16.04下内核模块解析
  19. C#读写记事本(txt)文件
  20. 初识gulp

热门文章

  1. 2018.4.3 Linux环境变量与变量
  2. Python 继承、派生、组合、接口、抽象类
  3. HTML5&lt;article&gt;元素
  4. mysql 安装简介
  5. Eclipse上进行java web项目的打包
  6. 【jquery】 form ajaxSubmit 问题
  7. GoF23种设计模式之结构型模式之装饰模式
  8. GoF23种设计模式之行为型模式之访问者模式
  9. 水题:UVa213- Message Decoding
  10. JAVA里的单引号和双引号及String和char的区别