大文件下载--断点续传--NSURLConnection

有了上一篇文章的铺垫直接上代码,下面是分析原理.

//  ViewController.m
//  大文件下载
//  Created by apple on 15/11/11.
//  Copyright © 2015年 LDSmallCat. All rights reserved.
#import "ViewController.h"
#import "DACircularProgressView.h"//进度条的第三方框架
@interface ViewController ()<NSURLConnectionDataDelegate>
//下载和暂停按钮
@property (weak, nonatomic) IBOutlet UIButton *button;
//用来写数据的文件句柄对象
@property(nonatomic,strong) NSFileHandle *writeHandle;
//文件的总大小.用已经下载的进度 除以 文件的总大小,做出进度条
@property(nonatomic,assign) long long totalLength;
//当前已经写入的文件大小.已经下载的,
@property(nonatomic,assign) long long currentLength;
///链接对象
@property (nonatomic, strong) NSURLConnection *conn;
//进度条
@property(nonatomic,weak) DACircularProgressView * circleView;
@end
@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    NSLog(@"didFailWithError");
}
//接收到响应就会调用
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    //下载完成后 再次点击的时候,如果为1就直接返回,不在下载,或弹框告诉用户已经存在,
    //需要将self.currentLength写入本地文件才能做到不会重复下载.就是说这个程序无法避免重复下载
    if (self.currentLength) return;
    //数据保存的路径
    NSString * caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString * filepath = [caches stringByAppendingPathComponent:@"download2.mp4"];
    //通过这个路径创建一个文件  到 沙盒中
    NSFileManager * mgr = [NSFileManager defaultManager];
    [mgr createFileAtPath:filepath contents:nil attributes:nil];
    //创建一个用来写入文件数据的文件句柄
    self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
    //获取文件总大小
    self.totalLength = response.expectedContentLength;
    NSLog(@"didReceiveResponse文件总大小%lld",self.totalLength);
}
//接受到数据就会调用,如果数据很大会被调用多次.边下边存储到沙盒,不会有内存问题
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    //移动到文件的最后面
    [self.writeHandle seekToEndOfFile];
    //数据写入沙盒
    [self.writeHandle writeData:data];
    //累计文件长度,通过循环不断增大这个值,在下面的方法中拿到这个值量化去下载任务
    //比如这里第一次拿到300字节,下面请求下载0-300的任务,下次拼接后为1000,下面请求下载300-1000
    //的任务,
    self.currentLength += data.length;
    self.circleView.progress = (double)self.currentLength / self.totalLength;
    //经过不断拼接,已经写入的数据,
    NSLog(@"didReceiveData   已经下载的数据%lld   ",self.currentLength);
}
//下载完成后调用,做些处理工作
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    //变量归零
    self.currentLength = 1;
    self.totalLength = 0;
    //关闭文佳
    [self.writeHandle closeFile];
    self.writeHandle = nil;
}
- (IBAction)downLoad:(UIButton *)sender{
    //状态取反
    sender.selected = ! sender.selected;
    //断点续传,断点下载
    if(sender.selected){
        //1.点击下载,创建URL,发送请求.url中不能有中文
        NSURL * url = [NSURL URLWithString:@"http://localhost/dawenjianyasuo.zip"];
        //2.请求
        NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
        self.currentLength = 0;
        //设置请求头.实现的要点在这里,此处的Rang属性实现了下载的控制,用self.currentLength
        //来保存已经下载了多少字节,
        NSString * range = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];
        [request setValue:range forHTTPHeaderField:@"Range"];
        //下载(创建完conn对象后,会自动发起一个异步请求)

        self.conn = [NSURLConnection connectionWithRequest:request delegate:self];
    }else{//一旦点击暂停创建的request就会销毁,再次点击下载时需要重新创建.
        [self.conn cancel];
        self.conn = nil;
    }
}
@end

整体流程:

原理会在下一篇文章中说明,

时间: 2024-10-06 22:08:26

大文件下载--断点续传--NSURLConnection的相关文章

OC - 16.大文件下载

大文件下载注意事项 若不对下载的文件进行转存,会造成内存消耗急剧升高,甚至耗尽内存资源,造成程序终止. 在文件下载过程中通常会出现中途停止的状况,若不做处理,就要重新开始下载,浪费流量. 大文件下载的解决方案 对下载文件进行处理,每下载一点数据,就将数据写到磁盘中(通常是沙盒中),避免在内存累积数据(NSURLConnection下载) 使用NSFileHandle类实现写数据 使用NSOutputStream类实现写数据 当下载任务终止时,记录任务终止时的位置信息,以便下次开始继续下载 大文件

iOS开发之网络编程--使用NSURLConnection实现大文件下载

主要思路(实现下载数据分段写入缓存中) 1.使用NSURLConnectionDataDelegate以及代理方法.2.在成功获取响应的代理方法中,获得沙盒全路径,并在该路径下创建空文件和文件句柄.3.在获取data的代理方法中,先设置句柄在沙盒全路径文件末尾,然后通过句柄写入data数据.4.在文件下载完的代理方法中,关闭句柄同时设置句柄引用为nil释放句柄和指针. 使用句柄的思路图(红色的箭头表示句柄,灰色的箭头表示移动的路径): 代码关键词: 类:NSFileHandle的方法 1.fil

iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄

前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传.    在实际开发中,输入输出流用的比较少,但是用起来也是很方便的.iOS开发用到的输入输出流和在Java中的输入输出流是几乎一样的,本质也是一个意思:将网络返回的数据当做流来处理.    输入输出的理解:输入到哪里?输出到哪里?这个问题不难理解,输入输出是要站着服务器角度来思考的,下面用图来解释:    代码关键词: 1.在接收到响应头的代理

NSURLConnection实现大文件下载

NSURLConnection实现大文件下载 1.方案:利用NSURLConnection和它的代理方法 1> 发送一个请求 // 1.URL NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"]; // 2.请求 NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 3.下载(创建完c

IOS NSURLConnection(大文件下载)

一.大文件下载 1.方案:利用NSURLConnection和它的代理方法1> 发送一个请求// 1.URLNSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];// 2.请求NSURLRequest *request = [NSURLRequest requestWithURL:url];// 3.下载(创建完conn对象后,会自动发起一个异步请求)[N

ios开发网络学习三:NSURLConnection小文件大文件下载

一:小文件下载 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> /** 注释 */ @property (nonatomic, strong) NSMutableData *fileData; @property (nonatomic, assign) NSInteger totalSize; @property (weak, nonatomic) IB

2016 - 1- 23 大文件下载

---恢复内容开始--- 一: 利用NSFileHandle对象实现大文件下载 1.要了解NSFileHandle的用法,注意下载完要关闭这个对象.还要记得每次写入之前将它的文件指针挪位! // // ViewController.m // 多值参数 // // Created by Mac on 16/1/23. // Copyright © 2016年 Mac. All rights reserved. // #define ZZFile [ [NSSearchPathForDirector

网络编程---(数据请求+slider)将网络上的大文件下载到本地,并打印其进度

网络编程---将网络上的大文件下载到本地,并打印其进度. 点击"开始传输"按钮,将网络上的大文件先下载下来,下载完成后,保存到本地. UI效果图如下:            具体代码如下: //  ViewController.m //  0611---数据请求+滚动条 #import "ViewController.h" unsigned long tempLength; @interface ViewController () <NSURLConnecti

源码0603-01-了解-大文件下载(NSOutputStream)

NSOutputStream 数据流的使用 // ViewController.m // 01-了解-大文件下载(NSOutputStream) #import "ViewController.h" @interface ViewController () <NSURLConnectionDataDelegate> /** 输出流对象 */ @property (nonatomic, strong) NSOutputStream *stream; @end @impleme