赞
踩
POST
Content-Type: multipart/form-data;
#define kBOUNDARY @"abc" -(void)uploadFile:(NSString *)urlString fieldName:(NSString *)fieldName filePath:(NSString *)filePath{ NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //设置post request.HTTPMethod = @"post"; //设置请求头 [request setValue:[NSString stringWithFormat:@"multipart/form-data;boundary=%@",kBOUNDARY] forHTTPHeaderField:@"Content-Type"]; //设置请求体 request.HTTPBody = [self makeBodyWithfieldName:fieldName filePath:filePath]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *_Nullable response,NSData *_Nullable data,NSError *_Nullable connectionError){ NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@",html); }]; } -(NSData *)makeBodyWithfieldName:(NSString *)fieldName filePath:(NSString *)filePath{ NSMutableData *mData = [NSMuatbelData data]; //第一部分 NSMutableString *mString = [NSMuatbleString string]; [mString appendFormat:@"--%@\r\n",kBOUNDARY]; [mString appendFormat:@"Content-Disposittion: form-data; name=\"%@\";filename=\"%@\"\r\n",fieldName,[filePath lastPathComponent]]; [mString appendString:@"Content-Type: image/hpeg\r\n"]; [mString appendString:@"\r\n"]; [nData appendData:[mString dataUsingEncoding:NSUTF8StringEncoding]]; //第二部分 //加载文件 NSData *data = [NSData dataWithContentsOfFile:filePath]; [mData appendData:data]; //第三部分 NSString *end = [NSString stringWithFormat:@"\r\n--%@--",kBOUNDARY]; [mData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]]; return mData.copy; }
name
表单的name
属性值filename
传递给服务器的文件名Content-Type
告诉服务器传递的文件类型text/plain image/jpeg image/jpg image/png application/octet-stream
等------WebKitFormBoundaryuWw18YzUxr2ygEJi--
NSArray
的循环block
进行拼接AFNetworking
HEAD
请求NSURLResponse
的属性MIMEType
返回的文件的类型 Content-Type
expectedContentLength
文件的预期大小(实际大小)suagestedFilename
建议保存的文件的名字data
是空的NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//设置post
request.HTTPMethod = @"post";
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *_Nullable response,NSData *_Nullable data,NSError *_Nullable connectionError){
NSLog(@"%@",response);
}];
GET
下载,但是直接保存到内存中再进磁盘,内存压力大,内存不够闪退,没有进度条[data writeToFile:@"/Users/Apple/Desktop/123.hm" atomically:YES];
NSURLConnectionDownloadDelegate
APP
文件保存,故放弃遵守协议<NSURLConnectionDownloadDelegate> NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSURLConnection *conn = [NSURLConnection alloc]initWithRequest:request delegate:self]; 代理方法: //下载进度,一段时间自动调用 -(void)connection:(NSURLConnection *)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes{ //bytesWritten 本次下载了多少字节 //totalBytesWritten 总共下载了多少字节 //expectedTotalBytes 文件的大小 float process = totalBytesWritten *1.0 /expectedTotalBytes; NSLog(@"%@",process); } //续传文件 -(void)connectionDidResumeDownloading:(NSURLConnection *)connection totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes{ } //下载完成调用 -(void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL{ //destinationURL下载文件的沙盒地址 } //处理错误 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"下载出错%@",error) }
NSURLConnectionDataDelegate
NSURLConnectionDownloadDelegate
继承自NSURLConnectionDataDelegate
//接受到响应头 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ //记得写这个@property(nonatomic,assign)long long currentFileSize; self.currentFileSize = response.expectedContentlength; } //一点一点接受数据 //用一个NSMutableData存数据,记得重写他的get函数 //@property(nonatomic,strong)NSMutableData currentFileSize; -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //记得写这个@property(nonatomic,assign)long long currentFileSize; self.currentFileSize += data.length; //文件慢慢保存 [self.mutableData appendData:data]; //进度条 float process = self.currentFileSize *1.0 /expectedContentLength; NSLog(@"%@",process); } //下载完成 -(void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"下载完成!"); [self.mutableData writeToFile:@"/Users/Apple/Desktop/111.hm" atomically:YES]; } //处理错误 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"下载出错%@",error) }
NSFileHandle
(读写二进制文件)和NSOutputStream
NSFileManager
(创建 删除 复制文件)-(void)saveFile:(NSData *)data{ //保存文件路径 NSString *filePath = @"/Users/Apple/Desktop/111.hm""; //文件创建,文件不存在返回的是nil NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:filePath]; // if(file == nil){ //data直接写入 [data writeToFile:path atomically:YES]; }else{ //文件指针移动到文件尾 [file seekToEndOfFile]; //文件指针移动到指定位置 //[file seekToFileOffset:<#(unsigned long long)>]; //写入文件 [file writeData:data]; //关闭文件句柄 [file closeFile]; } }
@property(nonatomic,strong)NSOutputStream *stream;
//创建流
self.stream = [NSOutputStream outputSteamToFileAtPath:@"/Users/Apple/Desktop/111.hm",append:YES];
//打开流
[self.stream open];
//保存数据
[self.stream write:data.bytes maxLength:data.length];
//关闭流
[self.stream close];
是在消息循环机制上运行,如果在子线程,需要手动开启子线程的消息循环机制,故不推荐
@property(nonatomic,copy)NSString *filePath; @property(nonatomic,copy)NSString *currentFileSize; //下载之前获取服务器文件的大小和名称 -(void)getServerFileInfo:(NSURL *)url{ NSURLRequest *request = [NSURLRequest requestWtihURL:url]; request.HTTPMethod = @"head"; NSURLResponse *response = nil; //&response用于参数传值 [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL]; //当前文件大小 self.currentFileSize = response.expectedContentLength; //文件路径 self.filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:response.suggestedFilename]; } //获取本地文件的大小,和服务器文件比较 //判断文件是否存在,不存在0 -(long long)checkLocalFileInfo{ long long fileSize = 0; NSFileManager *fileManager = [NSFileManager defaultManager]; if(![fileManager fileExistsAtPath:self.filePath]){ //返回文件的属性字典 NSDictionary *attrs = [fileManager attributesOfItemAtPath:self.selfPath error:NULL]; fileSize = attrs.fileSize if(fileSize == self.expectedContentLength){ fileSize = -1;//下载完成 } if(fileSize > self.expectedContentLength){ fileSize = 0;//下载错误,删除文件,重新下载 //删除文件 [fileManager removeItemAtPath:self.filePath error:NULL]; } } return fileSize; } //下载文件 需要异步下载的话,加个线程 -(void)downloadFile(NSURL *)url{ //NSOperation多线程 [[NSOperationQueue new] addOperationWithBlock:^{ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url] //修改请求头 //Range:bytes=x-y 从x下载到y //Range:bytes=x- 从x下载到最后 //Range:bytes=-y 从头下载到y [request setVale:[NSString stringWithFormat:@"bytes=%lld-",self.currentFileSize] forHTTPHeaderField:@"Range"]; //当前线程的消息循环中,默认子线程的消息循环是没有开启的,需要手动开启 NSURLConnection *con = [[NSURLConnecttion alloc]initWithRequest:request delegate:self]; //开启子线程的消息循环 [[NSRunLoop currentRunLoop] run]; }]; } //主流程下载 -(void)download:(NSString *)urlString successBlock:(void(^)(NSString *path))successBlock processBlock:(void(^)(float process))processBlock errorBlock:(void(^)(ESError *error))errorBlock{ //便于传值 self.successBlock = successBlock; self.processBlock = processBlock; self.errorBlock = errorBlock; NSURL *url = [NSURL URLWithString:urlString]; //下载之前获取服务器文件的大小和名称 [self getServerFileInfo:url]; //获取本地文件的大小,和服务器文件比较 self.currentFileSize = [self checkLocalFileInfo]; //下载完成 if(self.currentFileSize == -1){ if(self.successBlock){ //需要回到主线程 dispatch_async(dispatch_get_main_queue(),^{ self.successBlock(self.filePath); }); } return; } //下载文件 [self downloadFile:url]; }
//暂停下载
-(void)pause{
[self.conn cancel];
}
@property(noatomic,copy) void(^successBlock)(NSString *path);
@property(noatomic,copy) void(^processBlock)(float process);
@property(noatomic,copy) void(^errorBlock)(NSError *error);
//在合适的地方加入
if(self.processBlock){
self.pro cessBlock(process);
}
if(self.successBlock){
//需要回到主线程GCD
dispatch_async(dispatch_get_main_queue(),^{
self.successBlock(self.filePath);
});
}
if(self.errorBlock){
self.errorBlock(error);
}
-(void)drawRect:(CGRect)rect{ //Drawing code UIBezierPath *Path = [UIBezierPath bezierPath]; CGPoint center = CGPointMake(rect.size.width/2,rect.size.height/2); CGFloat radius = MIS(center.x,center.y); CGFloat startAngle = -M_PI_2;//绘制的起点 CGFloat endAngle = 2 * M_PI * self.process + startAngle; //设置 [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; path.lineWidth = 5 ; path.lineCapStyle = kCGLineCapRound; [[UIColor orangeColor] setStroke]; //开始绘制 [path stroke]; }
写一个单例模式的管理类,拥有一个操作缓存池
@property(noatomic,strong) NSMuatbleDictionary *downloaderCache; //懒加载 -(NSMuatbleDictionary *)downloaderCache{ if(_downloaderCache == nil){ _downloaderCache = [NSMuatbleDictionary dictionaryWithCapacity:10]; } return _downloaderCache; } //使用的时候把他添加到缓存池 if(self.downloaderCache[urlString]){ NSLog(@"正在下载了!"); return; }else{ //开始下载 ... //添加到下载缓存池里面 [self.downloaderCache setObject:downloader forKey:urlString]; //成功之后和失败记得移出缓存池 [self.downloaderCache removeObjectForKey:urlString]; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。