二:断点续传

    2_1 沙盒的介绍

    沙盒中的文件和目录

    1.app(应用程序)包 -》一些程序资源 和二进制程序(运行时不能对包中的文件进行写操作)

    2.Documents(存放一些自己的文件)保留存储一些重要信息

    3.Library -》这个目录下有两个子目录:Caches 和 Preferences

    Preferences 目录:包含应用程序的偏好设置文件。用NSUserDefaults类来取得和设置应用程序的偏好设置.    Caches 目录:做一些缓存数据,保存应用程序再次启动过程中需要的信息,比如下载图片的缓存。

    4.tmp  这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息

    1,获取沙盒家目录路径的函数:
    NSString *homeDir = NSHomeDirectory();


    2,获取沙盒Documents目录路径的方法:
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];

    还可以 NSString * docStr = [NSHomeDirectory()  stringByAppendingPathComponent:@"Documents"];


    3,获取Caches目录路径的方法:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachesDir = [paths objectAtIndex:0];


    4,获取tmp目录路径的方法:
    NSString *tmpDir = NSTemporaryDirectory();


    5,获取应用程序程序包中资源文件路径的方法:
    例如获取程序包中一个mp3资源(apple.mp3)路径的方法:
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@“apple”ofType:@”mp3”];

    告诉服务器从哪里开始下载

    添加请求头

[request addValue:[NSString stringWithFormat:@"bytes=%llu-“,_cacheFileSize] forHTTPHeaderField:@"Range"];

    响应的时候获取需要下载多大: [response expectedContentLength];

#define URL @"http://dlsw.baidu.com/sw-search-sp/soft/2a/25677/QQ_V4.0.0.1419920162.dmg"

    考虑到下载数据应该单独分离开,我们封装一个自己的文件断点下载类:ZZFileDownloader, 然后通过代理或block实现数据数据之间的交互

    提供接口类似于:

-(void)start:(NSString *)urlStr; 
     -(void)stop;

    

    数据结构和逻辑分析:

NSString *_downloadDocPath; // 这个路径标示下载的文件所在的文件夹路径, 这个文件夹路径可以是固定的,只要是下载的文件都放在这个文件夹中 
     NSFileHandle *_fileHandle; // 文件句柄,用于往指定的文件里写入数据 
     long long downloadFileSize; // 当前下载了多少字节 
     long long totalFileSize; // 文件总大小

    2_2 实现逻辑,首先创建文件夹路径_downloadDocPath

- (NSString *)downloadDocPath{ 
         if (_downloadDocPath == nil) { 
            //找到沙河中的Document目录 
         NSString *documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; 
         // 
         //NSLog(@"%@",documentPath); 
          
         NSString * downloadPath = [documentPath stringByAppendingPathComponent:@"zzFileDownload"]; 
         BOOL isSuccess = [[NSFileManager defaultManager]createDirectoryAtPath:downloadPath withIntermediateDirectories:YES attributes:nil error:nil]; 
         if (isSuccess) { 
             NSLog(@"文件夹创建成功"); 
             } 
         _downloadDocPath = downloadPath; 
         } 
         return _downloadDocPath; 
     }

    2_3 实现方法 -(void)start:(NSString *)urlStr; 在正式开始下载之前做好准备工作:

/** 
      * 1. 确保文件存在(根据传过来的urlStr关联文件),如果文件不存在,则创建,并得到文件路径 
      * 2. 根据文件路径获取它的大在小 _downloadFileSize [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize] 
      * 3. 设置写入此文件的文件句柄 _writeFileHandle [NSFileHandle fileHandleForWritingAtPath:filePath] 
      */

    2_4 实现断点续传的核心代码:设置请求的Range头域

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlStr]]; 
     [request addValue:[NSString stringWithFormat:@"bytes=%llu-",_downloadFileSize] forHTTPHeaderField:@"Range"];

    2_5 在<NSURLConnectionDataDelegate>代理方法中更新值并把值传出去

    失败回调

    当接收到服务器的响应时重新给totalFileSize赋值:self.totalFileSize = self.downloadFileSize + response.expectedContentLength;

    当接收到服务器每次发过来的数据时把数据通过文件句柄写入文件,并_downlaodFileSize和回调

    成功时(下载完成)回调

 

    2_6 实现stop方法

    断开connection, 关闭文件句柄