IOS文件下载总结(一)

来源:互联网 发布:mac资源管理器快捷键 编辑:程序博客网 时间:2024/05/22 09:43

  • 写在前面
  • 使用NSURLConnection下载文件
    • 断点下载
      • HTTP Range
      • 断点下载示例代码

写在前面

文件下载,特别是大文件下载,禁止使用NSMutleData接收,这样的操作会使加大内存消耗。

使用NSURLConnection下载文件

思路:边下载,边将文件写入到本地缓存。选择使用NSURLConnection的代理方法,当服务器收到相应后创建本地缓存文件,当服务器每次返回数据时将接收到的数据写入到缓存文件中。

@interface ViewController ()<NSURLConnectionDataDelegate>//文件句柄@property (nonatomic, strong) NSFileHandle *writeHandle;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    NSURL *url = [NSURL URLWithString:@"http:www.xxxxxx.com/resource/xxx.mp4"];    NSURLRequest *request = [NSURLRequest requestWithURL:url];    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];}#pragma mark NSURLConnectionDataDelegate的代理方法/** *  当接收到服务器响应的时候调用 * *  @param connection *  @param response   响应 */-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    //沙盒路径    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];    //缓存文件路径    NSString *cachesFilePath = [cachesPath stringByAppendingPathComponent:@"xxxx.mp4"];    //创建一个缓存文件    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager createFileAtPath:cachesFilePath contents:nil attributes:nil];    //创建对文件操作的句柄    self.writeHandle = [NSFileHandle fileHandleForReadingAtPath:cachesFilePath];}/** *  每次接收到服务器返回的数据时调用 * *  @param connection *  @param data     服务器返回的数据 */-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    //文件句柄移到文件末尾    [self.writeHandle seekToEndOfFile];    //写文件    [self.writeHandle writeData:data];}/** *  数据下载完毕时调用 * *  @param connection */- (void)connectionDidFinishLoading:(NSURLConnection *)connection{    //关闭文件操作    [self.writeHandle closeFile];    self.writeHandle = nil;}

断点下载

断点下载主要用于大文件,可以暂停下载和恢复下载。

HTTP Range

想服务器请求数据时,可以设置请求头的Range可以指定每次从网络下载数据的大小格式:    bytes=0-499 表示[0, 499]    bytes=500-  表示500字节以后的所有字节    bytes=500-600,800-900 同时指定几个范围

断点下载示例代码

@interface ViewController ()<NSURLConnectionDataDelegate>//文件句柄@property (nonatomic, strong) NSFileHandle *writeHandle;@property (nonatomic, strong) long long currentDownLoad;@property (nonatomic, strong) NSURLConnection *connection;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];}#pragma mark NSURLConnectionDataDelegate的代理方法/** *  当接收到服务器响应的时候调用 * *  @param connection *  @param response   响应 */-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    //沙盒路径    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];    //缓存文件路径    NSString *cachesFilePath = [cachesPath stringByAppendingPathComponent:@"xxxx.mp4"];    //创建一个缓存文件    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager createFileAtPath:cachesFilePath contents:nil attributes:nil];    //创建对文件操作的句柄    self.writeHandle = [NSFileHandle fileHandleForReadingAtPath:cachesFilePath];}/** *  每次接收到服务器返回的数据时调用 * *  @param connection *  @param data     服务器返回的数据 */-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    //文件句柄移到文件末尾    [self.writeHandle seekToEndOfFile];    //写文件    [self.writeHandle writeData:data];    //计算文件长度    self.currentDownLoad += data.length;}/** *  数据下载完毕时调用 * *  @param connection */- (void)connectionDidFinishLoading:(NSURLConnection *)connection{    //关闭文件操作    [self.writeHandle closeFile];    self.writeHandle = nil;}/** *  暂停按钮响应事件,根据按钮的状态,判断下载还是暂停 * *  @param sender */- (void)downLoadAction:(UIButton*)sender{    sender.selected = !sender.selected;    if (sender.selected) {        NSURL *url = [NSURL URLWithString:@"http:www.xxxxxx.com/resource/xxx.mp4"];        NSURLRequest *request = [NSURLRequest requestWithURL:url];        //设置请求头        NSString *range = [NSString stringWithFormat:@"bytes=%lld-", self.currentDownLoad];        [request setValue:range forKey:@"Range"];        self.connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];    }else{        [self.connection cancel];        self.connection = nil;    }}

注意的是:如果用户暂停下载之后退出了应用,那么就应该考虑缓存文件中文件的大小,然后根据文件的大小再去请求数据。

0 0
原创粉丝点击