IOS开发总结之文件下载(大文件下载)

时间:2021-06-23 20:58:55

1.直接用NSURLConnection下载

#import "ViewController.h"

#import "DACircularProgressView.h"

/**

 

 *  NSURLConnectionDataDelegate协议中的代理方法

 开始接收到服务器的响应时调用

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

 

 接收到服务器返回的数据时调用(服务器返回的数据比较大时会调用多次)

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

 

 服务器返回的数据完全接收完毕后调用

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection;

 

 请求出错时调用(比如请求超时)

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


 */


@interface ViewController () <NSURLConnectionDataDelegate>

/**

 *  用来写数据的文件句柄对象

 */

@property (nonatomic,strong)NSFileHandle *writeHandle;

/**

 *  文件的总大小

 */

@property (nonatomic,assign)longlong totalLength;

/**

 *  当前已经写入的文件大小

 */

@property (nonatomic,assign)longlong currentLength;


@property (nonatomic,weak)DACircularProgressView *circleView;//用这个类来添加下载进度条

@end


@implementation HMViewController


- (void)viewDidLoad

{

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

    /**

     *  DACircularProgress这个类添加下载进度条

     */

    DACircularProgressView *circleView = [[DACircularProgressViewalloc]init];

    circleView.frame = CGRectMake(100, 50, 100, 100);

    circleView.progressTintColor = [UIColorredColor];

    circleView.trackTintColor = [UIColorblueColor];

    circleView.progress = 0.01;

    [self.viewaddSubview:circleView];

    self.circleView = circleView;

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    // 1.URL

    NSURL *url = [NSURLURLWithString:@"http://hd.shijue.cvidea.cn/tf/140422/2330218/5355ca2

f3dfae93acb000001.JPEG"];

    // 2.请求

    NSURLRequest *request = [NSURLRequestrequestWithURL:url];

    // 3.下载(创建完conn对象后,会自动发起一个异步请求)

    [NSURLConnectionconnectionWithRequest:requestdelegate:self];

}

#pragma mark - NSURLConnectionDataDelegate代理方法

/**

 *  请求失败时调用(请求超时、网络异常)

 *

 *  @param error      错误原因

 */

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

{

    NSLog(@"didFailWithError");

}

/**

 *  1.接收到服务器的响应就会调用 (先搞一个0kb的文件,然后用writeHandle关联那个文件,最后写入数据

 *  @param response   响应

 */

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

{

    // 文件路径 沙盒中的caches的路径

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

    NSLog(@"caches = %@",caches);


    //用这个stringByAppendingPathComponent:方法会自动添加一个/表示这是个路径

    NSString *filepath = [cachesstringByAppendingPathComponent:@"photodownload.JPEG"];//先搞一个0kb的文件

    // 创建一个空的文件沙盒中

    NSFileManager *mgr = [NSFileManagerdefaultManager];

    [mgr createFileAtPath:filepathcontents:nilattributes:nil];

    

    // 创建一个用来写数据的文件句柄

    self.writeHandle = [NSFileHandlefileHandleForWritingAtPath:filepath];//然后用writeHandle关联那个文件

    // 获得文件的总大小

    self.totalLength = response.expectedContentLength;

}


/**

 *  2.当接收到服务器返回的实体数据时调用(具体内容,这个方法可能会被调用多次)

 *

 *  @param data       这次返回的数据

 */

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

{

    // 移动到文件的最后面

    [self.writeHandleseekToEndOfFile];

    

    // 将数据写入沙盒(先移动到最后面再拼接)

    [self.writeHandlewriteData:data]; //最后写入数据

    

    // 累计文件的长度

    self.currentLength += data.length;

    

    NSLog(@"下载进度:%f", (double)self.currentLength/self.totalLength);

    self.circleView.progress = (double)self.currentLength/self.totalLength;

}

/**

 *  3.加载完毕后调用(服务器的数据已经完全返回后)

 */

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    self.currentLength =0;

    self.totalLength =0;

    

    // 关闭文件

    [self.writeHandlecloseFile];

    self.writeHandle =nil;

}



command + shift + g 来到这个路径

/Users/admin/Library/Developer/CoreSimulator/Devices/250BF271-B5CD-45D2-B549-0EEB38E8AEA7/data/Containers/Data/Application/E51E876C-B8B3-4998-AD56-3239909F68A9/Library/Caches


就可以看到下载的文件了





2.用AFURLConnectionOperation下载

     // 1.URL

    NSURL *url = [NSURLURLWithString:@"http://hd.shijue.cvidea.cn/tf/140422/2330218/5355ca2

f3dfae93acb000001.JPEG"];

    // 2.请求

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //3. AFURLConnectionOperation

   AFURLConnectionOperation *operation = [[AFHTTPRequestOperationalloc]initWithRequest:request];

    operation.outputStream = [NSOutputStreamoutputStreamToFileAtPath:filePathappend:NO];

    self.hud.labelText =@"正在下载";

    [self.hudshow:YES];

    [self.hudhide:YESafterDelay:10];

    [operation setDownloadProgressBlock:^(NSUInteger bytesRead,longlong totalBytesRead,longlong totalBytesExpectedToRead) {

        //下载的进度,如 0.53,就是 53%

        float progress =   (float)totalBytesRead / totalBytesExpectedToRead;

        //下载完成后立即执行

        if (progress ==1.0) {

//            [self.hud hide:YES];

            _haveDowned =true;

            self.hud.labelText =@"下载成功!";

            [self.hudshow:YES];

            [self.hudhide:YESafterDelay:1];

            NSLog(@" 下载完成 progress = %f",progress);

        }else{

//            [self.hud hide:YES];

            self.hud.labelText =@"下载失败!";

            [self.hudshow:YES];

            [self.hudhide:YESafterDelay:1];

        }

    }];

    //下载完成的事件该方法会在下载完成后延迟 2秒左右执行 根据完成后需要处理的及时性不高,可以采用该方法

    [operation setCompletionBlock:^{

        //        NSLog(@"自然人凭证下载接口下载完成 ");

    }];

    [operation start];