比如请求的数据大小是0~1000的话断点续传的原理酒如同下面的分段解析
分块请求 Request 请求头 通过包含参数
如果下载 0~500 Range 0-500
500~1000 500-1000
200~800 200-800
200~最后 200-
例子:下载文件断点续下自定义下载工具类.m中
#import@interface downLoad : NSObject//传下载进度(block传值) 0~1
@property (nonatomic,strong) void(^progressValue)(float);//设置一个url 待下载的链接(url) 下载的路径(存储下载文件)//初始化方法-(instancetype)initWithURL:(NSString *)url toFirlPath:(NSString *)path;//开始下载-(void)start;//停止下载-(void)stop;@end定义下载工具类.h中#import "downLoad.h"#import@implementation downLoad
{
// 定义一个全局的发起下载的Connection对象
NSURLConnection *_connection;
// 计算当前下载的进度
unsigned long long _currentLength;
// 下载文件的总进度
long long _totalLength;
// 定义一个文件读写的句柄
NSFileHandle *_fileHandle;
NSString *_url;
NSString *_path;
}
//设置一个url 待下载的链接(url) 下载的路径(存储下载文件)
-(instancetype)initWithURL:(NSString *)url toFirlPath:(NSString *)path
{
if (self=[super init]) {
_url=url;
_path=path;
[self creatConnection:url file:path];
}
return self;
}
//封装之前的代码和方法
-(void)creatConnection:(NSString *)url file:(NSString *)path
{
NSURL *myURL=[NSURL URLWithString:url];
NSMutableURLRequest *request=[[NSMutableURLRequest alloc]initWithURL:myURL];
NSFileManager *manager=[NSFileManager defaultManager];
_fileHandle=[NSFileHandle fileHandleForUpdatingAtPath:path];
// 判断存不存在已下载数据的文件
if ([manager fileExistsAtPath:path]) {
// 如果存在计算出已经下载文件的大小
_currentLength =[_fileHandle seekToEndOfFile];
// 设置请求数据的范围 key : Range value @"bytes_currentLength-"
[request setValue:@"Range" forHTTPHeaderField:[NSString stringWithFormat:@"bytes=%llu-",_currentLength]];
}else{
// 不存在 创建文件
[manager createFileAtPath:path contents:nil attributes:nil];
// 设置文件的长度为0
_currentLength=0;
}
_connection=[[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
}
//开始下载
-(void)start
{
if (!_connection) {
// 数据为空得时候创建
[self creatConnection:_url file:_path];
}
[_connection start];
}
//停止下载
-(void)stop
{
[_connection cancel];
_connection=nil;
}
//实现下载的协议方法 NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//请求数据成功后 服务器返回一个数据信息(reponse)包含所下载数据的总长度
// 数据总长度
_totalLength=response.expectedContentLength;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//一点点的返回数据 同时实现一点点的写入文件
[_fileHandle writeData:data];
// 同步增加已下载数据的字节数_
_currentLength +=[data length];
// 调用之前定义的block来时刻改变prograssView的值(调用block把当前的下载进度传过去)
self.progressValue((float)_currentLength/_totalLength);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//下载完成了给个UI提示
UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:nil message:@"下载完成" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
}
@end
系统vc类的.h中
#import "ViewController.h"
#import "downLoad.h"
@interface ViewController ()
@end
@implementation ViewController
{
downLoad *_download;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 获取沙盒路径 拼接后 存入沙盒
NSString *path=[NSString stringWithFormat:@"%@/download.zip",NSHomeDirectory()];
// 获取url的路径
NSString *url =@"Http://10.0.179.123/1531/Xcode6.4.zip";
//创建下载对象
_download =[[downLoad alloc]initWithURL:url toFirlPath:path];
// 取消循环引用的条件
__weak ViewController *object=self;
// block 赋值
_download.progressValue=^(float value){
object.progress.progress=value;
};
NSLog(@"%@",path);
}
- (IBAction)start:(id)sender {
[_download start];
}
- (IBAction)stop:(id)sender {
[_download stop];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end