一、文件下载
获取资源文件大小有两张方式
1、
 
- HTTP HEAD方法  
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:kTimeout];  
- request.HTTPMethod = @"HEAD";  
- [NSURLConnection sendAsynchronousRequest:request queue:self.myQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {  
-     NSLog(@"%@", response);  
-     NSLog(@"---------------");  
-     NSLog(@"%@", data);  
- }];  
- 运行测试代码可以发现,HEAD方法只是返回资源信息,而不会返回数据体  
- 应用场景:  
- 获取资源Mimetype  
- 获取资源文件大小,用于端点续传或多线程下载  
 
2
 
 
- 使用块代码获取网络资源大小的方法  
- - (void)fileSizeWithURL:(NSURL *)url completion:(void (^)(long long contentLength))completion  
- {  
-     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:kTimeout];  
-     request.HTTPMethod = @"HEAD";   
-     NSURLResponse *response = nil;  
-     [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];  
-       
-     completion(response.expectedContentLength);  
- }  
 
确定每次下载数据包的伪代码实现
 
 
- - (void)downloadFileWithURL:(NSURL *)url  
- {  
-     [self fileSizeWithURL:url completion:^(long long contentLength) {  
-         NSLog(@"文件总大小:%lld", contentLength);          
-         
-                while (contentLength > kDownloadBytes) {  
-             NSLog(@"每次下载长度:%lld", (long long)kDownloadBytes);  
-             contentLength -= kDownloadBytes;  
-         }  
-         NSLog(@"最后下载字节数:%lld", contentLength);  
-     }];  
- }  
 
HTTP Range的示例
通过设置Range可以指定每次从网路下载数据包的大小
Range示例
bytes=0-499 从0到499的头500个字节
bytes=500-999 从500到999的第二个500字节
bytes=500- 从500字节以后的所有字节
bytes=-500 最后500个字节
bytes=500-599,800-899 同时指定几个范围
Range小结
- 用于分隔
前面的数字表示起始字节数
后面的数组表示截止字节数,没有表示到末尾
, 用于分组,可以一次指定多个Range,不过很少用
 
 
- 分段Range代码实现  
- long long fromBytes = 0;  
- long long toBytes = 0;  
- while (contentLength > kDownloadBytes) {  
-     toBytes = fromBytes + kDownloadBytes - 1;  
-     NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", fromBytes, toBytes];  
-     NSLog(@"range %@", range);  
-     fromBytes += kDownloadBytes;  
-     contentLength -= kDownloadBytes;  
- }  
- fromBytes = fromBytes + contentLength - 1;  
- NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", fromBytes, toBytes];  
- NSLog(@"range %@", range);  
 
 
- 分段下载文件  
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeout];  
- NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", from, end];  
- [request setValue:range forHTTPHeaderField:@"Range"];  
-   
- NSURLResponse *response = nil;  
- NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];  
-       
- NSLog(@"%@-%@-%ld", range, response, (unsigned long)data.length);  
- 提示:  
- 如果GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是200(OK)  
 
 
- 将数据写入文件  
- NSFileHandle *fp = [NSFileHandle fileHandleForWritingAtPath:self.cachePath];  
- if (!fp) {  
-     [data writeToFile:self.cachePath atomically:YES];  
- } else {  
-     
-     [fp seekToEndOfFile];  
-     
-     [fp writeData:data];  
-     
-     [fp closeFile];  
- }  
 
 
- 检查文件大小  
- if ([[NSFileManager defaultManager] fileExistsAtPath:self.cachePath]) {  
-     NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:self.cachePath error:NULL];  
-     return [dict[NSFileSize] longLongValue];  
- } else {  
-     return 0;  
- }  
-   
- 提示:由于数据是追加的,为了避免重复从网络下载文件,在下载之前  
- 判断缓存路径中文件是否已经存在  
- 如果存在检查文件大小  
- 如果文件大小与网络资源大小一致,则不再下载  
 
全部代码如下
 
 
-   
- #import "MJViewController.h"  
- #import "FileDownload.h"  
-   
- @interface MJViewController ()  
- @property (nonatomic, strong) FileDownload *download;  
- @property (weak, nonatomic) IBOutlet UIImageView *imageView;  
- @end  
-   
- @implementation MJViewController  
-   
- - (void)viewDidLoad  
- {  
-     [super viewDidLoad];  
-       
-     self.download = [[FileDownload alloc] init];  
-     [self.download downloadFileWithURL:[NSURL URLWithString:@"http://localhost/itcast/images/head4.png"] completion:^(UIImage *image) {  
-           
-         self.imageView.image = image;  
-     }];  
- }  
-   
- @end  
 
 
-   
- #import "FileDownload.h"  
- #import "NSString+Password.h"  
-   
- #define kTimeOut        2.0f  
- #define kBytesPerTimes  20250  
-   
- @interface FileDownload()  
- @property (nonatomic, strong) NSString *cacheFile;  
- @property (nonatomic, strong) UIImage *cacheImage;  
- @end  
-   
- @implementation FileDownload  
- - (UIImage *)cacheImage  
- {  
-     if (!_cacheImage) {  
-         _cacheImage = [UIImage imageWithContentsOfFile:self.cacheFile];  
-     }  
-     return _cacheImage;  
- }  
-   
- - (void)setCacheFile:(NSString *)urlStr  
- {  
-     NSString *cacheDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];  
-     urlStr = [urlStr MD5];  
-       
-     _cacheFile = [cacheDir stringByAppendingPathComponent:urlStr];  
- }  
-   
- - (void)downloadFileWithURL:(NSURL *)url completion:(void (^)(UIImage *image))completion  
- {  
-     
-     dispatch_queue_t q = dispatch_queue_create("cn.itcast.download", DISPATCH_QUEUE_SERIAL);  
-       
-     dispatch_async(q, ^{  
-         NSLog(@"%@", [NSThread currentThread]);  
-           
-         
-         self.cacheFile = [url absoluteString];  
-           
-         
-         long long fileSize = [self fileSizeWithURL:url];  
-         
-         long long cacheFileSize = [self localFileSize];  
-           
-         if (cacheFileSize == fileSize) {  
-             dispatch_async(dispatch_get_main_queue(), ^{  
-                 completion(self.cacheImage);  
-             });  
-             NSLog(@"文件已经存在");  
-             return;  
-         }  
-           
-         
-         long long fromB = 0;  
-         long long toB = 0;  
-         
-         while (fileSize > kBytesPerTimes) {  
-             
-             
-             toB = fromB + kBytesPerTimes - 1;  
-               
-             
-             [self downloadDataWithURL:url fromB:fromB toB:toB];  
-               
-             fileSize -= kBytesPerTimes;  
-             fromB += kBytesPerTimes;  
-         }  
-         [self downloadDataWithURL:url fromB:fromB toB:fromB + fileSize - 1];  
-   
-         dispatch_async(dispatch_get_main_queue(), ^{  
-             completion(self.cacheImage);  
-         });          
-     });  
- }  
-   
- #pragma mark 下载指定字节范围的数据包  
- - (void)downloadDataWithURL:(NSURL *)url fromB:(long long)fromB toB:(long long)toB  
- {  
-     NSLog(@"数据包:%@", [NSThread currentThread]);  
-       
-     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeOut];  
-       
-     
-     NSString *range = [NSString stringWithFormat:@"Bytes=%lld-%lld", fromB, toB];  
-     [request setValue:range forHTTPHeaderField:@"Range"];  
-     NSLog(@"%@", range);  
-       
-     NSURLResponse *response = nil;  
-     NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];  
-       
-     
-     [self appendData:data];  
-       
-     NSLog(@"%@", response);  
- }  
-   
- #pragma mark - 读取本地缓存文件大小  
- - (long long)localFileSize  
- {  
-     
-     NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:self.cacheFile error:NULL];  
-     NSLog(@"%lld", [dict[NSFileSize] longLongValue]);  
-       
-     return [dict[NSFileSize] longLongValue];  
- }  
-   
- #pragma mark - 追加数据到文件  
- - (void)appendData:(NSData *)data  
- {  
-     
-     NSFileHandle *fp = [NSFileHandle fileHandleForWritingAtPath:self.cacheFile];  
-     
-     if (!fp) {  
-         [data writeToFile:self.cacheFile atomically:YES];  
-     } else {  
-         
-         
-         [fp seekToEndOfFile];  
-         
-         [fp writeData:data];  
-         
-         [fp closeFile];  
-     }  
- }  
-   
- #pragma mark - 获取网络文件大小  
- - (long long)fileSizeWithURL:(NSURL *)url  
- {  
-     
-     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:kTimeOut];  
-       
-     
-     
-     request.HTTPMethod = @"HEAD";  
-   
-     
-     NSURLResponse *response = nil;  
-       
-     [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];  
-       
-     
-     NSLog(@"%lld", response.expectedContentLength);  
-       
-     return response.expectedContentLength;  
- }  
-   
- @end  
 
 
 
二、文件上传
代码如下
 
-   
- #import "MJViewController.h"  
- #import "UploadFile.h"  
-   
- @interface MJViewController ()  
-   
- @end  
-   
- @implementation MJViewController  
-   
- - (void)viewDidLoad  
- {  
-     [super viewDidLoad];  
-   
-     UploadFile *upload = [[UploadFile alloc] init];  
-       
-     NSString *urlString = @"http://localhost/upload.php";  
-       
-     NSString *path = [[NSBundle mainBundle] pathForResource:@"头像1.png" ofType:nil];  
-     NSData *data = [NSData dataWithContentsOfFile:path];  
-       
-     [upload uploadFileWithURL:[NSURL URLWithString:urlString] data:data];  
- }  
-   
- @end  
 
 
-   
- #import "UploadFile.h"  
-   
- @implementation UploadFile  
- static NSString *boundaryStr = @"--";   
- static NSString *randomIDStr;           
- static NSString *uploadID;              
-   
- - (instancetype)init  
- {  
-     self = [super init];  
-     if (self) {  
-         randomIDStr = @"itcast";  
-         uploadID = @"uploadFile";  
-     }  
-     return self;  
- }  
-   
- #pragma mark - 私有方法  
- - (NSString *)topStringWithMimeType:(NSString *)mimeType uploadFile:(NSString *)uploadFile  
- {  
-     NSMutableString *strM = [NSMutableString string];  
-       
-     [strM appendFormat:@"%@%@\n", boundaryStr, randomIDStr];  
-     [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\n", uploadID, uploadFile];  
-     [strM appendFormat:@"Content-Type: %@\n\n", mimeType];  
-       
-     NSLog(@"%@", strM);  
-     return [strM copy];  
- }  
-   
- - (NSString *)bottomString  
- {  
-     NSMutableString *strM = [NSMutableString string];  
-       
-     [strM appendFormat:@"%@%@\n", boundaryStr, randomIDStr];  
-     [strM appendString:@"Content-Disposition: form-data; name=\"submit\"\n\n"];  
-     [strM appendString:@"Submit\n"];  
-     [strM appendFormat:@"%@%@--\n", boundaryStr, randomIDStr];  
-       
-     NSLog(@"%@", strM);  
-     return [strM copy];  
- }  
-   
- #pragma mark - 上传文件  
- - (void)uploadFileWithURL:(NSURL *)url data:(NSData *)data  
- {  
-     
-     NSString *topStr = [self topStringWithMimeType:@"image/png" uploadFile:@"头像1.png"];  
-     NSString *bottomStr = [self bottomString];  
-       
-     NSMutableData *dataM = [NSMutableData data];  
-     [dataM appendData:[topStr dataUsingEncoding:NSUTF8StringEncoding]];  
-     [dataM appendData:data];  
-     [dataM appendData:[bottomStr dataUsingEncoding:NSUTF8StringEncoding]];  
-       
-     
-     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:2.0f];  
-       
-     
-     request.HTTPBody = dataM;  
-       
-     
-     request.HTTPMethod = @"POST";  
-       
-     
-     NSString *strLength = [NSString stringWithFormat:@"%ld", (long)dataM.length];  
-     [request setValue:strLength forHTTPHeaderField:@"Content-Length"];  
-       
-     
-     NSString *strContentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", randomIDStr];  
-     [request setValue:strContentType forHTTPHeaderField:@"Content-Type"];  
-       
-     
-     [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {  
-           
-         NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];  
-         NSLog(@"%@", result);  
-     }];  
- }  
-   
-   
-   
- @end  
 ios 多线程文件下载与上传, post数据
原文:http://www.cnblogs.com/zwios/p/4183698.html