• ios开发网络学习四:NSURLConnection大文件断点下载


    #import "ViewController.h"
    
    @interface ViewController ()<NSURLConnectionDataDelegate>
    @property (weak, nonatomic) IBOutlet UIProgressView *progressView;
    
    @property (nonatomic, assign) NSInteger totalSize;
    @property (nonatomic, assign) NSInteger currentSize;
    /** 文件句柄*/
    @property (nonatomic, strong)NSFileHandle *handle;
    /** 沙盒路径 */
    @property (nonatomic, strong) NSString *fullPath;
    /** 连接对象 */
    @property (nonatomic, strong) NSURLConnection *connect;
    @end
    
    @implementation ViewController
    
    
    - (IBAction)startBtnClick:(id)sender {
        [self download];
    }
    - (IBAction)cancelBtnClick:(id)sender {
        [self.connect cancel];
    }
    - (IBAction)goOnBtnClick:(id)sender {
        [self download];
    }
    
    //内存飙升
    -(void)download
    {
        //1.url
        // NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];
        
        NSURL *url = [NSURL URLWithString:@"http://www.33lc.com/article/UploadPic/2012-10/2012102514201759594.jpg"];
        
        //2.创建请求对象
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        //设置请求头信息,告诉服务器值请求一部分数据range
        /*
         bytes=0-100 
         bytes=-100
         bytes=0- 请求100之后的所有数据
         */
        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
        [request setValue:range forHTTPHeaderField:@"Range"];
        NSLog(@"+++++++%@",range);
        
        //3.发送请求
        NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self];
        self.connect = connect;
    }
    
    #pragma mark ----------------------
    #pragma mark NSURLConnectionDataDelegate
    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        NSLog(@"didReceiveResponse");
        
        //1.得到文件的总大小(本次请求的文件数据的总大小 != 文件的总大小)
        // self.totalSize = response.expectedContentLength + self.currentSize;
        
        if (self.currentSize >0) {
            return;
        }
        
        self.totalSize = response.expectedContentLength;
        
        //2.写数据到沙盒中
        self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.jpg"];
        
        NSLog(@"%@",self.fullPath);
        
        //3.创建一个空的文件
        [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];
        
        //NSDictionary *dict = [[NSFileManager defaultManager]attributesOfItemAtPath:self.fullPath error:nil];
        
        //4.创建文件句柄(指针)
        self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
    }
    
    -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        //1.移动文件句柄到数据的末尾
        [self.handle seekToEndOfFile];
        
        //2.写数据
        [self.handle writeData:data];
        
        //3.获得进度
        self.currentSize += data.length;
        
        //进度=已经下载/文件的总大小
        NSLog(@"%f",1.0 *  self.currentSize/self.totalSize);
        self.progressView.progress = 1.0 *  self.currentSize/self.totalSize;
        //NSLog(@"%@",self.fullPath);
    }
    
    -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
    }
    
    -(void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        //1.关闭文件句柄
        [self.handle closeFile];
        self.handle = nil;
        
        NSLog(@"connectionDidFinishLoading");
        NSLog(@"%@",self.fullPath);
    }
    @end

    #####6.0  大文件断点下载

    (1)实现思路

        在下载文件的时候不再是整块的从头开始下载,而是看当前文件已经下载到哪个地方,然后从该地方接着往后面下载。可以通过在请求对象中设置请求头实现。

    (2)解决方案(设置请求头)

    ```

    //2.创建请求对象

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        //2.1 设置下载文件的某一部分

        // 只要设置HTTP请求头的Range属性, 就可以实现从指定位置开始下载

        /*

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

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

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

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

         */

        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentLength];

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

    ```

    (3)注意点(下载进度并判断是否需要重新创建文件)

    ```objc

    //获得当前要下载文件的总大小(通过响应头得到)

        NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

        //注意点:res.expectedContentLength获得是本次请求要下载的文件的大小(并非是完整的文件的大小)

        //因此:文件的总大小 == 本次要下载的文件大小+已经下载的文件的大小

        self.totalLength = res.expectedContentLength + self.currentLength;

        NSLog(@"----------------------------%zd",self.totalLength);

        //0 判断当前是否已经下载过,如果当前文件已经存在,那么直接返回

        if (self.currentLength >0) {

            return;

        }

    ```

  • 相关阅读:
    黑盒测试用例输入:等价类划分方法
    jar包/class文件如何快速反编译成java文件
    html表格单元格添加斜下框线的方法
    Linux常用命令操作文档
    压力、负载、性能测试工具总结(持续更新。。。)
    压力测试、负载测试及性能测试异同
    Mac os x安装IDEAL及配置JDK和Maven
    RMQ问题总结,标准RMQ算法的实现
    [c++ IO加速]快速输入输出
    [coj 1353 Guessing the Number]kmp,字符串最小表示法
  • 原文地址:https://www.cnblogs.com/cqb-learner/p/5861459.html
Copyright © 2020-2023  润新知