基于NSURLConnection的多线程队列下载器,实现断点续传

//
//  TYDownLoader.h
//  TYDownLoader
//
//  Created by 邴天宇 on 15/3/24.
//  Copyright (c) 2015年 邴天宇. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface TYDownLoader : NSObject
// @pragma 下载远程url(连接到服务器的路径)
@property (nonatomic, retain) NSString * url;

// @pragma  下载后的存储路径
@property (nonatomic, retain) NSString * destinationPath;

//@pragma file name;
@property (nonatomic, retain) NSString * fileName;

// @pragma  下载 state 监测
@property (nonatomic,readonly,getter=isDownLoading) BOOL Downloading;

//  @pragma 监听下载进度
@property (nonatomic, copy) void(^progressHandler) (double progress);

//  @pragma 监听完成
@property (nonatomic, copy) void (^finishHandler)(BOOL);

//  @pragma 监听错误
@property (nonatomic, copy) void (^errorHandler)(NSError * error);

//  @pragma 监听下载速度
@property (nonatomic, copy) void (^DownloadSpeed) (long long number);

/**
 *  暂停 下载
 */
- (void)pause;



/**
 *  开始  下载
 */
- (void)start;
/*!
 *  建立下载
 *
 *  @param url  网址
 *  @param name 文件名字
 */
+ (TYDownLoader * )setDownLoaderMessageUrl:(NSString *)url name:(NSString *)name


//
//  TYDownLoader.m
//  TYDownLoader
//
//  Created by 邴天宇 on 15/3/24.
//  Copyright (c) 2015年 邴天宇. All rights reserved.
//

#import "TYDownLoader.h"

@interface TYDownLoader ()<NSURLConnectionDataDelegate>

//文件数据
@property(nonatomic,retain)NSMutableData *fileData;
//文件句柄
@property(nonatomic,retain)NSFileHandle *writeHandle;


//当前获取到的数据长度
@property(nonatomic,assign)long long currentLength;
//完整数据长度
@property(nonatomic,assign)long long sumLength;


//是否正在下载
@property (nonatomic,assign,getter=isdownLoading) BOOL downLoading;

//请求对象
@property (nonatomic,retain) NSURLConnection * connt;

@property (nonatomic, assign)BOOL finish;

@end



重写init方法,,设置下载路径.判断文件是否创建,如果未创建,那么创建文件夹

 - (id)init

{

    self = [super init];

    if (self) {

        //  1. 创建文件 存数路径

        NSString * caches = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];

        NSString * Path = [NSString stringWithFormat:@"%@/DownLoade/Temp",caches];

        

          NSString * Path2 = [NSString stringWithFormat:@"%@/DownLoade/Caches",caches];

        NSFileManager * mgr = [NSFileManager defaultManager];

        if (![mgr isExecutableFileAtPath:Path]) {

            [mgr createDirectoryAtPath:Path withIntermediateDirectories:YES attributes:nil error:nil];

        }

        if (![mgr isExecutableFileAtPath:Path2]) {

            [mgr createDirectoryAtPath:Path2 withIntermediateDirectories:YES attributes:nil error:nil];

        }

    }

    return self;

}



#pragma mark -开始下载

 - (void)start

{

    _Downloading = YES;

    

//    创建一个下载请求

    NSURL * URL = [NSURL URLWithString:self.url];

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:URL];

    

    

//    设置请求头 信息

    NSString * requestHeader = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];

    [request setValue:requestHeader forHTTPHeaderField:@"Range"];

    

//    发送网络请求

    self.connt = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [_connt setDelegateQueue:self.queue];

    [self.connt start];

}


#pragma mark - 暂停下载

 - (void)pause

{

    _Downloading = NO;


    //    取消   发送 请求

    [self.connt cancel];

//    取消 请求 对象

    self.connt = nil;

    

}



- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

    

#warning 判断是否是第一次连接, 如果是则 不再进行 下列创建

    if (self.sumLength) return;

    

    

    //  1. 创建文件 存数路径

    NSString * caches = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];

    NSString * Path = [NSString stringWithFormat:@"%@/DownLoade/Temp",caches];

    NSLog(@"DownLoader = %@",Path);

    

    NSFileManager * mgr = [NSFileManager defaultManager];

    if (![mgr isExecutableFileAtPath:Path]) {

//        [mgr createFileAtPath:Path contents:nil attributes:nil]; 不好使

        [mgr createDirectoryAtPath:Path withIntermediateDirectories:YES attributes:nil error:nil];

    }

    NSString * filepath = [NSString stringWithFormat:@"%@/%@.caf",Path,self.fileName];

    self.destinationPath = filepath;

    //    2.创建一个空得文件路径

    [mgr createFileAtPath:filepath contents:nil attributes:nil];

    //    3.创建写数据的文件柄

    self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];

    

    //    4.

    //4.获取完整的文件的长度

    self.sumLength=response.expectedContentLength;

    

}



- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    //    累加接收到得数据

    self.currentLength += data.length;

    //      计算当前进度(转换为double型的)

    double progress= (double)self.currentLength/self.sumLength;

    if (self.progressHandler) {

        self.progressHandler(progress);

    }

//    NSLog(@"-----%f",progress);

//    监测 下载 速度

//    self.DownloadSpeed(data.length);

    

//    NSLog(@"接收到得服务器数据! --- %ld",data.length);

    

    //    data写入创建的空文件中,但是不能使用writeTofile(会覆盖)

    //    移动到文件的尾部

    [self.writeHandle seekToEndOfFile];

    //    从当前移动的位置,写入数据

    [self.writeHandle writeData:data];

}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    NSLog(@"下载完毕");

    //    关闭连接,不在输入 数据在文件中

        [self.writeHandle closeFile];

    

    //    在下载完毕后对进度进行清空

    self.currentLength = 0;

    self.sumLength = 0;

    

    if (self.finishHandler) {

        self.finishHandler(YES);   // 下载完成后 通知 控制器

    }

//      如果文件下载完成 那么 移动 caches 文件夹当中

    NSString * caches = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];

    NSString * Path = [NSString stringWithFormat:@"%@/DownLoade/Caches",caches];

    

    

    NSFileManager * mgr = [NSFileManager defaultManager];

    if (![mgr isExecutableFileAtPath:Path]) {

        [mgr createFileAtPath:Path contents:nil attributes:nil];

    }

    NSString * filepath = [NSString stringWithFormat:@"%@/%@.caf",Path,self.fileName];

    NSError * error;

    [mgr moveItemAtPath:self.destinationPath toPath:filepath error:&error];

    

    if (error) {

        NSLog(@"write to file Error = %@",error);

    }

}


- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

//    向服务器 发送 错误 信息

    if (self.errorHandler) {

        self.errorHandler(error);

    }

}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值