zoukankan      html  css  js  c++  java
  • 文件下载 NSURLConnection——文件下载与上传

    一、文件下载 

    重点:NSURLConnection的代理方法不是NSURLConnectionDelegate,而是NSURLConnectionDataDelegate

    1.下载小文件,只适合几百k,1、2M的文件

    //1.设置网址
    //2.加载请求
    //3.设置代理
    //4.实现代理方法下载文件
     NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1492791082124&di=fc642407b4ec19430334653a9b873cff&imgtype=0&src=http%3A%2F%2Fi0.szhomeimg.com%2FUploadFiles%2FBBS%2F2006%2F10%2F24%2F27567833_1950.442.jpg"];  
     NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
    代理实现
    #pragma mark ---NSURLConnectionDelegate
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
        NSLog(@"下载失败%@",error);
    }
    //下载响应
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    //获取文件大小
        _totalSize = response.expectedContentLength;
    }
    //下载数据
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        //拼接数据
        [_mudata appendData:data];
        //获取当前进度
        NSLog(@"%f",1.0*_mudata.length/_totalSize);
    }
    //下载完成
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection{
        
        NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"1.jpg"];
        [_mudata writeToFile:fullPath atomically:YES];
    }

      缺点:[_mudata appendData:data],会使内存暴涨,而且下载完毕后内存不会下降

    2.通过句柄来下载大文件

    #pragma mark ----------------------
    #pragma mark NSURLConnectionDataDelegate
    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        NSLog(@"didReceiveResponse");
        
        //1.得到文件的总大小(本次请求的文件数据的总大小)
        self.totalSize = response.expectedContentLength;
        
        //2.写数据到沙盒中
        self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];
        
        //3.创建一个空的文件
        [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes: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)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        //1.关闭文件句柄
        [self.handle closeFile];
        self.handle = nil;
        NSLog(@"connectionDidFinishLoading");
        NSLog(@"%@",self.fullPath);
    }
    

     3.通过断点续传来下载大文件(初级版)

    设置请求头,如果文件存在就继续下载

    //与上面不同的是请求头增加了Range
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        NSString *Range = [NSString stringWithFormat:@"bytes=%zd",_currentSize];
        [request setValue:Range forHTTPHeaderField:@"Range"];
    //下面判断文件是否存在不同,如果大于0就返回,不好的地方,删除了文件就不能再下载,待之后完善
    //接受响应
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
        NSLog(@"%@",response);
        NSLog(@"%@",response.MIMEType);
        //如果放在最前面,文件大小就需要加上当前文件的大小
        //如果有下载返回,只适用于当前
        //设置沙盒文件
        //创建空文件用NSFileManager
        //句柄指向该文件
        _totalSize = response.expectedContentLength+_currentSize;
        if(_currentSize > 0){
            NSLog(@"文件已经下载");
            return;
        }
        _fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"downFile.jpg"];
        //contents内容为空,
        [[NSFileManager defaultManager] createFileAtPath:_fullPath contents:nil attributes:nil];
        _fileHandle = [NSFileHandle fileHandleForWritingAtPath:_fullPath];
       
    }
    //接受数据
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
        //将句柄移动到文件末尾
        //通过句柄写入数据
        //获取文件进度
        if (_currentSize <=1) {
            _currentSize += data.length;
            NSLog(@"%f",1.0*_currentSize/_totalSize);
        }
        [_fileHandle seekToEndOfFile];
        [_fileHandle writeData:data];
        _progressView.progress = 1.0*_currentSize/_totalSize;
    }
    

       缺点:删除了以后不能重新下载  

     4.文件上传,NSURLConnection上传比较比较奇葩

    //文件上传
    - (void)fileUpload{
        //1.确认请求路径
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
        //2.创建可变请求
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        //3.设置请求方法
        request.HTTPMethod = @"POST";
        //4.设置请求头信息,Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryjv0UfA04ED44AhWx
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"];
        
        //5.拼接请求体参数
        NSMutableData *fileData = [NSMutableData data];
        /*
         --分隔符
         Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png"
         Content-Type: image/png(MIMEType:大类型/小类型)
         空行
         文件参数
         */
        [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        //name:file 服务器规定的参数
        //filename:Snip20160225_341.png 文件保存到服务器上面的名称
        //Content-Type:文件的类型
        [fileData appendData:[@"Content-Disposition: form-data; name="file"; filename="Snip20170424_7.png"" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:KNewLine];
        
        //image图片
        UIImage *image = [UIImage imageNamed:@"Snip20170424_7"];
        //UIImage --->NSData
        NSData *imageData = UIImagePNGRepresentation(image);
        [fileData appendData:imageData];
        [fileData appendData:KNewLine];
        //非文件参数
        //分隔符,
        //非文件参数
        /*
         --分隔符
         Content-Disposition: form-data; name="username"
         空行
         123456
         */
        [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:[@"Content-Disposition: form-data; name="username"" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        [fileData appendData:KNewLine];
        [fileData appendData:[@"123456" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileData appendData:KNewLine];
        //结尾标识符
        /*
         --分隔符--
         */
        [fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
        
        //6.设置请求体,请求体二进制数据
        request.HTTPBody = fileData;
        //发送请求
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
            //解析数据
            NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
        }];
    }
    

      

  • 相关阅读:
    Python之格式化unix时间戳
    Python简单的验证码生成
    Python字符串常用的一些东西
    PHP explode()函数
    PHP函数number_format()
    PHP简单的计算位数的函数
    python之列表推导式
    python之把列表当做队列使用
    python之列表操作的几个函数
    python之map函数
  • 原文地址:https://www.cnblogs.com/TheYouth/p/6746158.html
Copyright © 2011-2022 走看看