iOS进阶_WebDav(五.WebDav的上传进度&多线程下载思路)

WebDav的上传进度

#import "ViewController.h"

@interface ViewController ()<NSURLSessionTaskDelegate>
/** 会话  */
@property(nonatomic,strong)NSURLSession * session;
@end

@implementation ViewController

-(NSURLSession *)session
{
    if (!_session) {
        NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
        _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
    }
    return _session;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self putUpload]; 
}

#pragma mark - <上传演练>
-(void)putUpload{
    //1.url - URL是直接保存在服务器上的文件名
    NSURL * url = [NSURL URLWithString:@"http://192.168.31.180/uploads/123.wmv"];
    //2.请求
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    //设置请求方法-webdav上传需要使用put方法
    request.HTTPMethod = @"PUT";
    //设置身份验证的数据
    NSString * authStr = [self base64Encode:@"admin:123456"];
    authStr = [@"BASIC " stringByAppendingString:authStr];
    //设置请求头
    [request setValue:authStr forHTTPHeaderField:@"Authorization"];

    //3.session
    //上传的源文件的路径!!
    NSURL * fileUrl = [[NSBundle mainBundle] URLForResource:@"abc.wmv" withExtension:nil];
    // 上传任务如果跟进进度,可以同时使用代码块Blcok的方式
    [[self.session uploadTaskWithRequest:request fromFile:fileUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        NSLog(@"%@ %@",str,response);

    }] resume];
}

#pragma mark - <代理>

/**
 参数:
 session
 task

 bytesSent                  本次发送的字节数
 totalBytesSent             已经发送的字节数
 totalBytesExpectedToSend   总字节数(文件总大小)
 */
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
    float progress = (float)totalBytesSent / totalBytesExpectedToSend;
    NSLog(@"%f %@",progress,[NSThread currentThread]);
}

多线程下载思路

无论是上传还是下载默认都是在单线程中的
例如面试中会被问道:如何实现多线程下载(注意:多线程不是指子线程!)

多线程下载同一个文件的实现思路

1.获取服务器上的文件大小
2.在本地创建一个相同大小的文件,所有字节都是0(注意:写入文件不能使用输出流NSOutputStream,而是需要使用NSFileHande)
3.开启多条线程(假设开启两条线程)

这里写图片描述

两条线程分别拿Rang bytes0-4,和Rang bytes5-8的数据

这里写图片描述

当其中一条线程拿到数据后,Rang bytes会逐渐缩减
这里写图片描述

写入文件的时候,使用的是NSFileHande,根据seekOffset依次顺序写入
1、记录每一条线程当前的offset
2、如果要支持多线程下载且断点续传,就需要建立一个plist/json保存每一条线程末次执行的offset

注意:其实在实际开发中,移动端不适合多线程下载,因为消耗资源大,会出现耗电快,手机发烫现象。

那能否支持多线程上传文件呢?

答案是不能!服务器不可能为了一个特殊的用户开启多线线程,提交只能顺序提交

猜你喜欢

转载自blog.csdn.net/wtdask/article/details/80420384