NSURLSession使用NSURLSessionDataTask实现大文件下载,使用NSFileHandle实现一边接收数据,一边存到沙盒

NSURLSession实现大文件下载,使用NSFileHandle实现一边接收数据,一边存到沙盒

//文件句柄(指针) NSFileHandle实现边接收边写数据到沙盒中

/*

 特点:在写数据的时候边写数据边移动位置

 使用步骤:

 (1)创建空的文件

 (2)创建文件句柄指针指向该文件

 (3)当接收到数据的时候,使用该句柄来写数据

 (4)当所有的数据写完,应该关闭句柄指针

 

#import "ViewController.h"

@interface ViewController ()<NSURLSessionDataDelegate>

@property (nonatomic, assign) NSInteger totalSize;  //文件的总大小
@property (nonatomic, assign) NSInteger currentSize; //当前已经下载的数据大小
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (nonatomic, strong) NSFileHandle *handle;
@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //01 确定资源路径
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
    
    //02 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //03 创建会话对象 设置代理
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    //04 创建下载请求Task
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
    
    //05 发送请求
    [dataTask resume];
}

#pragma mark -----------------------
#pragma mark NSURLSessionDataDelegate
//01 接收到响应的时候调用
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    //得到本次请求的文件数据大小
    self.totalSize = response.expectedContentLength;
    
    //0 拼接获取文件的存储路径
    //得到文件的名称:得到请求的响应头信息,获取响应头信息中推荐的文件名称
    NSString *fileName = [response suggestedFilename];
    
    NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    
    //拼接文件的存储路径(沙盒路径cache) + 文件名
    NSString *fullPath = [cache stringByAppendingPathComponent:fileName];

    
    //(1)创建空的文件
    [[NSFileManager defaultManager] createFileAtPath:fullPath contents:nil attributes:nil];
    
    
    //(2)创建文件句柄指针指向该文件
    self.handle = [NSFileHandle fileHandleForWritingAtPath:fullPath];
    
    
    //告诉系统应该接收数据
    completionHandler(NSURLSessionResponseAllow);
}

//02 接收到服务器返回数据的时候调用 可能会调用多次
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    //(3)当接收到数据的时候,使用该句柄来写数据
    [self.handle writeData:data];
   
    //计算进度
    self.currentSize +=data.length;
    NSLog(@"%f",1.0 * self.currentSize / self.totalSize);
    self.progressView.progress = self.currentSize / self.totalSize;
}

//03 下载完成或者是失败的时候调用
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    // (4)当所有的数据写完,应该关闭句柄指针
    [self.handle closeFile];
}

//文件句柄(指针) NSFileHandle实现边接收边写数据到沙盒中
/*
 特点:在写数据的时候边写数据边移动位置
 使用步骤:
 (1)创建空的文件
 (2)创建文件句柄指针指向该文件
 (3)当接收到数据的时候,使用该句柄来写数据
 (4)当所有的数据写完,应该关闭句柄指针
 
 */

@end

 

posted on 2019-03-19 16:42  大圣ios博客  阅读(255)  评论(0编辑  收藏  举报