代码地址:https://code.csdn.net/super_man_ww/duandianxuchuan_medio/tree/master
二:断点续传
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, 关闭文件句柄