断点续传

本文介绍了一种基于iOS客户端的断点续传技术实现方案,包括如何利用HTTP Range请求头进行分段下载、进度显示及本地缓存管理等关键技术点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

断点续传的实现思路

    1、每次一进来,先给总大小和已经下载的大小赋值,判断若不是从头下载,则显示进度条
    2、暂停的时候,取消请求,并用 NSUserDefaults记录下载的暂停位置(客户端记录)
    3、继续下载的时候,设置下载的起始位置
         http协议的请求头的设置:
         Range : bytes=0-499   表示头500个字节
         Range : bytes=500-999 表示第二个500字节
         Range : bytes=-500    表示最后500个字节
         Range : bytes=500-    表示500字节以后的范围
         Range : bytes=0-0,-1  第一个和最后一个字节
    4、续传写文件时,总是从文件末尾追加写文件

效果图

这里写图片描述

代码实现

—————————viewDidLoad方法
    //--------每次一进来,先给总大小和已经下载的大小赋值,显示进度条
    //取得上次下载数据的大小
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    recevieTotal = [[userDefaults objectForKey:@"RecevieTotal"] floatValue];
    total = [[userDefaults objectForKey:@"Total"] floatValue];

    //判断是否是第一次下载显示进度条
    if (total > 0) {
        CGFloat progress = recevieTotal / total;
        _progressView.progress = progress;
        _progressLabel.text = [NSString stringWithFormat:@"%.2f%%", progress * 100];
    }
—————————downLoad方法
if (!isDownload) {
        //1、构建URL
        NSURL *url = [NSURL URLWithString:@"http://free2.macx.cn:8182/tools/other4/iStatMenus511b17.dmg"];

        //2、构建请求request
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        //设置断点续传
        if (recevieTotal > 0) {
            //设置继续下载的位置
            NSString *value = [NSString stringWithFormat:@"bytes=%d-", (int)recevieTotal];
            [request setValue:value forHTTPHeaderField:@"Range"];
        }

        //3、发送异步请求
        _connection = [NSURLConnection connectionWithRequest:request delegate:self];
        isDownload = YES;

        //获取字符串
        NSString *urlStr = url.absoluteString;
        //获取urlStr的最后一部分
        NSString *fileName = [urlStr lastPathComponent];
        //写入文件,拼接路径
        _filePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", fileName];

        //判断文件是否存在,如果不存在,再创建
        if (![[NSFileManager defaultManager] fileExistsAtPath:_filePath]) {
            //创建文件
            [[NSFileManager defaultManager] createFileAtPath:_filePath contents:nil attributes:nil];
        }
    }
—————————pause方法
    //拿到请求对象,并且取消请求
    [_connection cancel];
    _connection = nil;

    //将缓存文件写入数据,防止最后下载的不够500KB的数据没有保存
    [self appendFileData:self.receiveData];
    /*
     NSUserDefaults可以存取一些轻量级的本地数据(短小的信息)

     保存一个登陆界面的数据,用户名、密码之类的,个人觉得使用NSUserDefaults是首选。下次再登陆的时候就可以直接从NSUserDefaults里面读取上次登陆的信息

     但是并不是所有的东西都能往里放的。
     NSUserDefaults只支持: NSString, NSNumber, NSDate, NSArray, NSDictionary, BOOL.
     */
    //本地保存下载文件的大小和总文件的大小
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:@(recevieTotal) forKey:@"RecevieTotal"];

    [userDefaults setObject:@(total) forKey:@"Total"];

    //将数据同步写入文件
    [userDefaults synchronize];
    isDownload = NO;
—————————接收响应的方法---- NSHTTPURLResponse响应
    self.receiveData = [[NSMutableData alloc] init];
    //判断总大小是否为0,若为0,说明从头下载,需要获取文件总大小
    if (total == 0) {
        //获取响应头 --》 获取数据总大小
        total = [[response.allHeaderFields objectForKey:@"Content-Length"] floatValue];
        NSLog(@"total is %.2f", total);
    }
—————————接收数据的方法----实时接收
    [self.receiveData appendData:data];
    //计算进度: 已经接收数据的总大小 / 文件总大小
    recevieTotal += data.length;
    double progress = recevieTotal / total;
    //刷新UI
    self.progressView.progress = progress;
    self.progressLabel.text = [NSString stringWithFormat:@"%.2f%%", progress * 100];

    //判断缓冲数据的数据大小是否 > 500kB
    if (self.receiveData.length > 500 * 1000) {
        //往文件中写入数据
        [self appendFileData:self.receiveData];
        //清空:清空的是数据,
        [self.receiveData setData:nil];
    }
—————————接收完数据的方法
    //将最后一个缓存文件写入文件
    if (self.receiveData.length < 500 * 1000) {
        [self appendFileData:self.receiveData];
        [self.receiveData setData:nil];
    }
    _progressLabel.text = @"下载完成";
    isDownload = NO;
----------------fileHandle拼接写入文件
- (void)appendFileData:(NSData *)data
{
    if (data.length == 0) {
        return;
    }
    //使用NSFileHandle写文件,此文件必须已经创建,NSFileHangdle不会创建文件
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:_filePath];

    //将数据插入到写入点
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:data];

    //关闭文件,确保写入完成
    [fileHandle closeFile];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值