文件下载
如果文件比较小,下载方式会比较多
- 直接用NSData的+ (id)dataWithContentsOfURL:(NSURL *)url;
- 利用NSURLConnection发送一个HTTP请求去下载
- 如果是下载图片,还可以利用SDWebImage框架
大文件下载
- 方案一:利用NSURLConnection和它的代理方法
1.发送一个请求
123456 // 1.URLNSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/videos.zip"];// 2.请求NSURLRequest *request = [NSURLRequest requestWithURL:url];// 3.下载(创建完conn对象后,会自动发起一个异步请求)[NSURLConnection connectionWithRequest:request delegate:self];2.在代理方法中处理服务器返回的数据
1234567891011121314151617181920212223242526272829303132333435 /**在接收到服务器的响应时:1.创建一个空的文件2.用一个句柄对象关联这个空的文件,目的是:方便后面用句柄对象往文件后面写数据*/- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{// 文件路径NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];NSString *filepath = [caches stringByAppendingPathComponent:@"videos.zip"];// 创建一个空的文件 到 沙盒中NSFileManager *mgr = [NSFileManager defaultManager];[mgr createFileAtPath:filepath contents:nil attributes:nil];// 创建一个用来写数据的文件句柄self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];}/**在接收到服务器返回的文件数据时,利用句柄对象往文件的最后面追加数据*/- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{// 移动到文件的最后面[self.writeHandle seekToEndOfFile];// 将数据写入沙盒[self.writeHandle writeData:data];}/**在所有数据接收完毕时,关闭句柄对象*/- (void)connectionDidFinishLoading:(NSURLConnection *)connection{// 关闭文件[self.writeHandle closeFile];self.writeHandle = nil;}注意点:千万不能用NSMutableData来拼接服务器返回的数据
3.断点续传
通过设置请求头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,不过很少用
- 方案二:NSURLConnection发送异步请求的方法
1.block形式 - 除开大文件下载以外的操作,都可以用这种形式
123456789101112 [NSURLConnection sendAsynchronousRequest:<}];```>>2.代理形式 - 一般用在大文件下载>>```objectivec// 1.URLNSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/login?username=123&pwd=123"];// 2.请求NSURLRequest *request = [NSURLRequest requestWithURL:url];// 3.下载(创建完conn对象后,会自动发起一个异步请求)[NSURLConnection connectionWithRequest:request delegate:self];
- 方案三:NSURLSession
1.使用步骤
- 获得NSURLSession对象
- 利用NSURLSession对象创建对应的任务(Task)
- 开始任务([task resume])
2.获得NSURLSession对象
123 [NSURLSession sharedSession]NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];3.任务类型
NSURLSessionDataTask
用途:用于非文件下载的GET\POST请求
12345 NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request];NSURLSessionDataTask *task = [self.session dataTaskWithURL:url];NSURLSessionDataTask *task = [self.session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {//download something ...}];NSURLSessionDownloadTask
用途:用于文件下载(小文件、大文件)
12345 NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url];NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {//download something ...}];4、下载大文件
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];// 1.得到session对象NSURLSession *session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]];// 2.创建一个下载taskNSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/test.mp4"];NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url];// 3.开始任务[task resume];// 如果给下载任务设置了completionHandler这个block,也实现了下载的代理方法,优先执行block/*** 下载完毕后调用** @param location 临时文件的路径(下载好的文件)*/- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{// location : 临时文件的路径(下载好的文件)NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];// response.suggestedFilename : 建议使用的文件名,一般跟服务器端的文件名一致NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];// 将临时文件剪切或者复制Caches文件夹NSFileManager *mgr = [NSFileManager defaultManager];// AtPath : 剪切前的文件路径// ToPath : 剪切后的文件路径[mgr moveItemAtPath:location.path toPath:file error:nil];}/*** 恢复下载时调用*/- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{// ....}/*** 每当下载完(写完)一部分时就会调用(可能会被调用多次)** @param bytesWritten 这次调用写了多少* @param totalBytesWritten 累计写了多少长度到沙盒中了* @param totalBytesExpectedToWrite 文件的总长度*/- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{double progress = (double)totalBytesWritten / totalBytesExpectedToWrite;NSLog(@"下载进度---%f", progress);}
文件上传
文件上传的步骤
1.设置请求头目的:告诉服务器请求体里面的内容并非普通的参数,而是包含了文件参数
1 [request setValue:@"multipart/form-data; boundary=heima" forHTTPHeaderField:@"Content-Type"];2.设置请求体
作用:存放参数(文件参数和非文件参数)
非文件参数
12345 [body appendData:HMEncode(@"--heima\r\n")];[body appendData:HMEncode(@"Content-Disposition: form-data; name=\"username\"\r\n")];[body appendData:HMEncode(@"\r\n")];[body appendData:HMEncode(@"张三")];[body appendData:HMEncode(@"\r\n")];文件参数
123456 [body appendData:HMEncode(@"--heima\r\n")];[body appendData:HMEncode(@"Content-Disposition: form-data; name=\"file\"; filename=\"test123.png\"\r\n")];[body appendData:HMEncode(@"Content-Type: image/png\r\n")];[body appendData:HMEncode(@"\r\n")];[body appendData:imageData];[body appendData:HMEncode(@"\r\n")];结束标记 :参数结束的标记
1 [body appendData:HMEncode(@"--heima--\r\n")];
文件的MIMEType
如何获得文件的MIMEType
1.百度搜索
2.查找服务器下面的某个xml文件
apache-tomcat-6.0.41\conf\web.xml3.加载文件时通过Reponse获得
12345678910 - (NSString *)MIMEType:(NSURL *)url{// 1.创建一个请求NSURLRequest *request = [NSURLRequest requestWithURL:url];// 2.发送请求(返回响应)NSURLResponse *response = nil;[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];// 3.获得MIMETypereturn response.MIMEType;}4.通过C语言函数
12345678910111213 + (NSString *)mimeTypeForFileAtPath:(NSString *)path{if (![[NSFileManager alloc] init] fileExistsAtPath:path]) {return nil;}CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL);CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);CFRelease(UTI);if (!MIMEType) {return @"application/octet-stream";}return NSMakeCollectable(MIMEType);}
文件解压缩
1.技术方案
1).第三方框架:SSZipArchive
2).依赖的动态库:libz.dylib2.压缩
1).第一个方法
12345 /**zipFile :产生的zip文件的最终路径directory : 需要进行的压缩的文件夹路径*/[SSZipArchive createZipFileAtPath:zipFile withContentsOfDirectory:directory];2.第二个方法
123456 /**zipFile :产生的zip文件的最终路径files : 这是一个数组,数组里面存放的是需要压缩的文件的路径files = @[@"/Users/apple/Destop/1.png", @"/Users/apple/Destop/3.txt"]*/[SSZipArchive createZipFileAtPath:zipFile withFilesAtPaths:files];3.解压缩
12345 /**zipFile :需要解压的zip文件的路径dest : 解压到什么地方*/[SSZipArchive unzipFileAtPath:zipFile toDestination:dest];