文件下载 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]);
    }];
}

  

原文地址:https://www.cnblogs.com/TheYouth/p/6746158.html