码迷,mamicode.com
首页 > 其他好文 > 详细

下载性能优化---断点缓存

时间:2015-09-10 11:13:53      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:我的文章

#import <UIKit/UIKit.h>

@interface ViewController :UIViewController<NSURLConnectionDataDelegate>

{

    BOOL isDownLoad;//标识是否正在下载

    double receiveTotal;//已经接收数据总的大小

}

@property (nonatomic,assign)double totalLength;//下载数据的总的大小

@property (nonatomic,strong)NSMutableData *receiveData;//接收的总数据

@property (weak, nonatomic) IBOutletUIProgressView *progressView;//进度条

@property (weak, nonatomic) IBOutletUILabel *progressLabel;//下载比例

 

@property (nonatomic,copy)NSString *filePath;//文件存储路径

@property (nonatomic,strong)NSURLConnection *connection;//网络请求对象

@end

 

#import "ViewController.h"

@interfaceViewController ()

@end

@implementationViewController

/*

 下载性能优化

 使用一个缓冲Data存储下载数据,当缓冲的数据>500KB时,将此缓冲数据写入文件,并且清除缓存数据,以节约内存空间

 */

/*

 断点续传的实现思路:

 1. 暂停的时候,记录下载的暂停位置

 2. 继续下载时,设置下载的起始位置

  http协议的请求头的设置:

 Range : bytes=0-499   表示头500个字节

 Range : bytes=500-999 表示第二个500字节

 Range : bytes=-500    表示最后500个字节

 Range : bytes=500-    表示500字节以后的范围

 Range : bytes=0-0,-1  第一个和最后一个字节

  3. 续传写入文件时,总是从文件末尾追加写入文件

 */

- (void)viewDidLoad {

    [superviewDidLoad];

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

    //获取下载文件的存储地址

     NSLog(@"%@",NSHomeDirectory());

   

    //取得已经下载文件的大小和文件总得大小

    NSUserDefaults *userDefauts = [NSUserDefaultsstandardUserDefaults];

    receiveTotal = [[userDefauts objectForKey:@"ReceiveTotal"] doubleValue];

    _totalLength = [[userDefauts objectForKey:@"Total"] doubleValue];

   

    //显示上一次下载的进度

    if (_totalLength > 0) {

        CGFloat progress = receiveTotal / _totalLength;

        self.progressView.progress = progress;

        self.progressLabel.text = [NSStringstringWithFormat:@"%.2f%%",progress];

    }

}

- (IBAction)downLoadAction:(UIButton *)sender {

    if (!isDownLoad) {

        //构建URL地址

        NSURL *url = [NSURLURLWithString:@"http://free2.macx.cn:8182/tools/other4/iStatMenus511b17.dmg"];

        //构建NSURLRequest请求

        NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:url];

        //设置断点续传

        if (receiveTotal > 0) {

            //设置续传下载的位置

            NSString *value = [NSStringstringWithFormat:@"bytes=%d-",(int)receiveTotal];

            [request setValue:value forHTTPHeaderField:@"Range"];

        }

        //发送异步请求

        _connection = [NSURLConnectionconnectionWithRequest:request delegate:self];

        isDownLoad = YES;

        //获取字符串-----获取当前要下载的文件的绝对地址

        NSString *urlStr = url.absoluteString;

        //获取urlStr的最后一部分

        NSString *fileName = [urlStr lastPathComponent];

        //写入文件

       _filePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@",fileName];

        //判断文件是否已经存在,如果不存在,需要创建

        if (![[NSFileManagerdefaultManager] fileExistsAtPath:_filePath]) {

            //创建文件

            [[NSFileManagerdefaultManager] createFileAtPath:_filePathcontents:nilattributes:nil];

        }   

    }

}

#pragma mark-NSURLConnectionDataDelegate

//服务器响应了

- (void)connection:(NSURLConnection *)connectiondidReceiveResponse:(NSHTTPURLResponse *)response

{

    //初始化

    self.receiveData = [[NSMutableDataalloc] init];

   

    //判断文件总的大小是否为0,如果为0,说明XO能够起始位置下载,需要获取文件的大小

    if (_totalLength == 0) {

        //获取所有的响应头

        NSDictionary *fields = response.allHeaderFields;

       

        //获取数据的总的大小

        NSNumber *dataTotal = [fields objectForKey:@"Content-Length"];

       

        _totalLength = [dataTotal doubleValue];

//        NSLog(@"_totalLength is%.2f",_totalLength);

 

    }

}

//接收数据

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

{

    [self.receiveDataappendData:data];

   

    //已经接收数据总的大小 / 总数据的大小 =下载进度

    receiveTotal += data.length;

    double progress = receiveTotal / _totalLength;

   

    //刷新UI

    self.progressLabel.text = [NSStringstringWithFormat:@"%.2f%%",progress * 100];

    self.progressView.progress = progress;

   

    if (self.receiveData.length >= 500 * 1000) {

        //往文件路径中写入数据----调用方法

        [selfappendFileData:self.receiveData];

        //清空数据

        self.receiveData.data = nil;

    }

 

}

//数据传输完成

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    //将最后一个文件数据写入文件

    if (self.receiveData.length < 500 * 1000) {

        //调用写入数据方法

        [selfappendFileData:self.receiveData];

        [self.receiveDatasetData:nil];

    }

    _progressLabel.text = @"下载完成";

    isDownLoad = NO;

}

- (void)appendFileData:(NSData *)data

{

    if (data.length == 0) {

        return;

    }

    //使用NSFileManager写入文件,此此文件比粗已经创建,NSFileHandle是不会创建文件的

    NSFileHandle *fileHandle = [NSFileHandlefileHandleForWritingAtPath:_filePath];

    //将数据插入到写入点

    [fileHandle seekToEndOfFile];

    [fileHandle writeData:data];

    //关闭文件,确保写入完成

    [fileHandle closeFile];

}

//暂停下载

- (IBAction)pauseDownLoadAction:(UIButton *)sender {

    //取消下载

    [_connectioncancel];

    _connection = nil;

    //将缓存数据写入文件中

    [selfappendFileData:self.receiveData];

   

    //本地保存已经下载文件的大小文件的总的大小

    NSUserDefaults *userDefaults = [NSUserDefaultsstandardUserDefaults];

    [userDefaults setObject:@(receiveTotal)forKey:@"ReceiveTotal"];

    [userDefaults setObject:@(_totalLength)forKey:@"ToTal"];

        //将数据同步写入文件

    [userDefaults synchronize];

    isDownLoad = NO;

}

@end


下载性能优化---断点缓存

标签:我的文章

原文地址:http://10585085.blog.51cto.com/10575085/1693321

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!