(有码)NSURLConnection大文件下载

来源:互联网 发布:手机看股软件 编辑:程序博客网 时间:2024/05/01 16:36

#import "ViewController.h"

@interface ViewController ()<NSURLConnectionDataDelegate>
//总长度
@property (nonatomic, assign) long long totalLength;
//传输数据
@property (nonatomic, strong) NSMutableData *dataM;
//写入路径
@property (nonatomic, copy) NSString *pathString;

//判断下载是否完成
@property (nonatomic, assign) BOOL finish;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //因为下载任务是在主线程下载,当更新进度条时会和主线程抢夺资源导致,更新UI变卡
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        //将中文字符串转码
        NSString *string = [[NSString stringWithFormat:@"http://127.0.0.1/电影.mp4"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        //url
        NSURL *url = [NSURL URLWithString:string];
        //请求
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        //创建连接
        //代理可以显示下载进度
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        //代理方法在主线程运行(当更新UI的时候不能进行下载,和NSTimer相同)(有例子)
        [connection setDelegateQueue:[[NSOperationQueue alloc] init]];
        
        [connection start];
        
        //当产生子线程时候,子线程中的Runloop默认不开启,我们要手动开启才行
        do {
            [[NSRunLoop currentRunLoop] run];
        } while (!self.finish);
       
    });
    
}
//接收到请求头
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    _totalLength = response.expectedContentLength;
    
    //设置文件的目标路径(suggestedFilename服务器建议的文件名)PathComponent路径节点
    self.pathString = [@"/Users/students/Desktop" stringByAppendingPathComponent:response.suggestedFilename];
    
    //在下载之前,判断文件是否存在,如果存在直接删除
    [[NSFileManager defaultManager] removeItemAtPath:self.pathString error:NULL];
}
//接收数据
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    //下载大文件要进行数据拼接,如果一次性下载完成会出现峰值问题
    
    //直接写入文件
//    NSFileManager -->做文件的复制,删除...
//    NSFileHandle --->文件句柄  写入读取,文件
    //建立句柄准备写入文件
    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.pathString];
    //如果不加句柄直接写入文件,上次写入的文件会被覆盖(如果文件不存在,句柄就不能写入文件,所以就要先写入一次)
    if (handle == nil) {
        [data writeToFile:self.pathString atomically:YES];
    }else{
        //将句柄挪到最后]
        [handle seekToEndOfFile];
        //写入文件
        [handle writeData:data];
        //关闭句柄,保证在下载过程中被修改
        [handle closeFile];
    }
}
//接收完成
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    
}
//接收失败
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    
}

#pragma mark----定时器
- (void)timer{
    
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(click) userInfo:nil repeats:YES];
    //将定时器加到当前线程循环,并且提升优先级
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
0 0
原创粉丝点击