25、26、27day-文件上传和下载&ASI&AFN

来源:互联网 发布:linux reaver 编辑:程序博客网 时间:2024/06/07 00:01

一、文件上传下载

1、小文件下载

直接用NSData的+ (id)dataWithContentsOfURL:(NSURL *)url;
利用NSURLConnection发送一个HTTP请求去下载
如果是下载图片,还可以利用SDWebImage框架
2、 HTTP Range

通过设置请求头Range可以指定每次从网路下载数据包的大小—–可以用于断点下载

 [request setValue:[NSString stringWithFormat:@"bytes=%lld-",self.currentDataLength] forHTTPHeaderField:@"Range"];

1)Range示例

bytes=0-4990499的头500个字节 bytes=500-999500999的第二个500字节bytes=500-  从500字节以后的所有字节bytes=-500  最后500个字节bytes=500-599,800-899  同时指定几个范围 

2)Range小结
- 用于分隔
前面的数字表示起始字节数
后面的数组表示截止字节数,没有表示到末尾
用于分组,可以一次指定多个Range,不过很少用

第三方解压缩框架——SSZipArchive

Adding to your project

Add SSZipArchive.h, SSZipArchive.m, and minizip to your project.Add the libz library to your target 需要引入libz.dylib框架

Usage

// UnzippingNSString *zipPath = @"path_to_your_zip_file";NSString *destinationPath = @"path_to_the_folder_where_you_want_it_unzipped";[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];// ZippingNSString *zippedPath = @"path_where_you_want_the_file_created";NSArray *inputPaths = [NSArray arrayWithObjects:                       [[NSBundle mainBundle] pathForResource:@"photo1" ofType:@"jpg"],                       [[NSBundle mainBundle] pathForResource:@"photo2" ofType:@"jpg"]                       nil];[SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];

4、multipart/form-data格式小结 --文件上传

设置Post的请求头(key value)

/*Content-Type   multipart/form-data; boundary=本次上传标示字符串(不能中文)*/[request setValue:@"multipart/form-data;boundary=hisun" forHTTPHeaderField:@"Content-Type"];

The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/.

文件上传的请求体中包含的内容

这里写图片描述

请求参数文件参数 --本次上传标示字符串(边界比请求头的boundary 增加--开头)Content-Disposition: form-data;  name="参数名"; filename="文件名"  Content-Type: MIMEType  (文件类型)文件具体数据非文件参数 --本次上传标示字符串(--边界)Content-Disposition: form-data;  name="参数名称";  参数值--边界–(结尾标记 )结尾标记(--边界--)

代码块

zip 压缩文件夹

NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];   NSString *filePath = [cachePath stringByAppendingPathComponent:@"images"];   NSString *zipPath = [cachePath stringByAppendingPathComponent:@"images.zip"];   NSLog(@"%@,%@",filePath,zipPath);   [SSZipArchive createZipFileAtPath:zipPath withContentsOfDirectory:filePath];

根据URL 获取mimeType

- (NSString *) mimeTypeWithUrl:(NSURL *)url{    NSURLResponse *response;    [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url] returningResponse:&response error:nil];    return response.MIMEType;}//    NSString *mimetype = [self mimeTypeWithUrl:[NSURL fileURLWithPath:@"/Users/devzkn/Desktop/minion_02.png"]];

使用NSMutableURLRequest文件上传

#define HSBasicUrl  @"http://127.0.0.1:8080/KNServer/"#define HSUrl(name) [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",HSBasicUrl,name]]#define HSFileBoundary @"hisun"#define HSFileEndedBounary [NSString stringWithFormat:@"--%@--",HSFileBoundary]#define HSFileStartBoundary [NSString stringWithFormat:@"--%@",HSFileBoundary]#define HSNewLine @"\r\n"#define HSStringEncoding(str) [str dataUsingEncoding:NSUTF8StringEncoding]#pragma mark - 文件上传- (void)upload:(NSString*)fileName mimeType:(NSString *)mimeType fileData:(NSData*)fileData params:(NSDictionary*)params{    //设置请求体    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:HSUrl(@"upload")];    //准备请求体数据    NSMutableData *data =[NSMutableData data];    /*     请求体:     1)文件参数     --本次上传标示字符串(边界)     Content-Disposition: form-data;  name="参数名"; filename="文件名"     Content-Type: MIMEType  (文件类型)     文件具体数据     2)非文件参数     --本次上传标示字符串(边界)     Content-Disposition: form-data;  name="参数名称"     参数值     3)边界–(结尾标记 )     */    [data appendData:HSStringEncoding(HSFileStartBoundary)];//分界线    [data appendData:HSStringEncoding(HSNewLine)];    NSString *disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"",@"file",fileName];    [data appendData:HSStringEncoding(disposition)];//参数名    [data appendData:HSStringEncoding(HSNewLine)];    NSString *mimeTypeStr = [NSString stringWithFormat:@"Content-Type:%@",mimeType];    [data appendData:HSStringEncoding(mimeTypeStr)];    [data appendData:HSStringEncoding(HSNewLine)];    [data appendData:HSStringEncoding(HSNewLine)];    [data appendData:fileData];    [data appendData:HSStringEncoding(HSNewLine)];    //设置非文件数据    [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {        [data appendData:HSStringEncoding(HSFileStartBoundary)];//分界线        [data appendData:HSStringEncoding(HSNewLine)];        NSString *disposition = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"",key];        [data appendData:HSStringEncoding(disposition)];//参数名        [data appendData:HSStringEncoding(HSNewLine)];        [data appendData:HSStringEncoding(HSNewLine)];        [data appendData:HSStringEncoding([obj description])];        [data appendData:HSStringEncoding(HSNewLine)];    }];    //结尾    [data appendData:HSStringEncoding(HSFileEndedBounary)];    [data appendData:HSStringEncoding(HSNewLine)];    [request setHTTPBody:data];    [request setHTTPMethod:@"post"];    [request setValue:[NSString stringWithFormat:@"multipart/form-data;boundary=%@",HSFileBoundary] forHTTPHeaderField:@"Content-Type"];    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {        NSLog(@"%@,%@",response,[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]);    }];}

NSURLSession-断点续传

- (NSURLSession *)session{    if (_session == nil) {        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue] ];    }    return _session;}#pragma mark - 断点下载- (IBAction)pause:(UIButton *)sender {    [sender setSelected:!sender.selected];    if (sender.selected) {        if (self.task == nil) {            if (self.resumeData) {                [self resumeDownLoad];//继续下载            }else{                [self startSessionWithConfiguration];//开始下载            }        }    }else{        [self pauseDownload];//暂停    }}#pragma mark - NSURLSessionDownloadDelegate 查看下载进度- (void) startSessionWithConfiguration{    NSLog(@"%s----start ",__func__);    [self.circularProgressView setProgress:0];    [self.button setSelected:YES];    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:HSURL(@"resources/videos/iPhoneSimulator6.1.sdk.zip")];    self.task = [self.session downloadTaskWithRequest:request];    [self.task resume];//执行任务}- (void)resumeDownLoad{    if (self.resumeData == nil) {        return;    }    NSLog(@"%s-----继续",__func__);    self.task = [self.session downloadTaskWithResumeData:self.resumeData];    [self.task resume];    self.resumeData = nil;}- (void)pauseDownload {    NSLog(@"%s------   暂停",__func__);    if (self.task == nil) {        return;    }    /*     A completion handler that is called when the download has been successfully canceled.     If the download is resumable, the completion handler is provided with a resumeData object. Your app can later pass this object to a session’s downloadTaskWithResumeData: or downloadTaskWithResumeData:completionHandler: method to create a new task that resumes the download where it left off.即包含了创建链接的URL和连接的头信息(Range)     */    HSweakself(weakself);    [self.task  cancelByProducingResumeData:^(NSData * _Nullable resumeData) {        weakself.resumeData = resumeData;        weakself.task = nil;    }];}/* Sent when a download task that has completed a download.  The delegate should * copy or move the file at the given location to a new location as it will be * removed when the delegate message returns. URLSession:task:didCompleteWithError: will * still be called. */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTaskdidFinishDownloadingToURL:(NSURL *)location{    NSString *filePath = HSCachePath(downloadTask.response.suggestedFilename);    NSLog(@"%s----%@ --%@ --%@",__func__,downloadTask.response,filePath,location.path);    //移动location文件到filePath    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager moveItemAtPath:location.path toPath:filePath error:nil];}/* Sent periodically to notify the delegate of download progress. */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask      didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWrittentotalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{    NSLog(@"%s----%@,bytesWritten:%lld,------totalBytesWritten:%lld,------totalBytesExpectedToWrite:%lld------%f%%",__func__,downloadTask,bytesWritten,totalBytesWritten,totalBytesExpectedToWrite,(double)totalBytesWritten*100.0/totalBytesExpectedToWrite);    [self.circularProgressView setProgress:(double)totalBytesWritten*1.0/totalBytesExpectedToWrite];}/* Sent when a download has been resumed. If a download failed with an * error, the -userInfo dictionary of the error will contain an * NSURLSessionDownloadTaskResumeData key, whose value is the resume * data. */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffsetexpectedTotalBytes:(int64_t)expectedTotalBytes{    NSLog(@"%s-----fileOffset:%lld,---expectedTotalBytes:%lld",__func__,fileOffset,expectedTotalBytes);}

NSURLConnection断点下载

#pragma mark - 断点下载- (IBAction)pause:(UIButton *)sender {    [sender setSelected:!sender.selected];    if (sender.selected) {//继续下载        NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8080/MJServer/resources/videos/iPhoneSimulator6.1.sdk.zip"];        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];        //设置Range        [request setValue:[NSString stringWithFormat:@"bytes=%lld-",self.currentDataLength] forHTTPHeaderField:@"Range"];        NSLog(@"%@",[NSString stringWithFormat:@"bytes=%lld-",self.currentDataLength]);        self.connection = [NSURLConnection connectionWithRequest:request delegate:self];    }else{//暂停下载        [self.connection cancel];        self.connection = nil;    }}#pragma mark - NSURLConnectionDataDelegate- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    self.response = (NSHTTPURLResponse*)response;    if (self.currentDataLength) {//断点之后的新请求,无需执行以下代码        return;    }    //创建一个和预期下载文件一样大小的文件到沙盒--以便多线程断点下载,的线程分工;----单线程断点下载只需创建一个空文件    NSString *filePath = HSCachePath([connection.currentRequest.URL lastPathComponent]);    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager createFileAtPath:filePath contents:nil attributes:nil];    //创建文件handle    self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];    self.totalDataLength = response.expectedContentLength;}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    self.currentDataLength += data.length;//    NSDictionary *dict = [self.response allHeaderFields];//    NSString *length = dict[@"Content-Length"];//获取预期长度//    NSString *length = self.response.expectedContentLength;        [self.circularProgressView setProgress:self.currentDataLength*1.0/self.totalDataLength];    [self.fileHandle seekToEndOfFile];    [self.fileHandle writeData:data];}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{    [self.fileHandle closeFile];    self.currentDataLength =0;}
原创粉丝点击