【iOS】文件下载小记
来源:互联网 发布:张艺兴和sm知乎 编辑:程序博客网 时间:2024/05/06 08:37
文件的下载分为NSURLConnection与NSURLSession两种,前一种有恨悠久的历史了。使用相对麻烦,后者是新出来的,增加了一些额外的功能。
一、NSURLConnection实现下载
TIPS:
1、当NSURLConnection下载时,得到的NSData写入文件时,data并没有占用多大内存. (即使文件很大)
2、一点点在传. 做的是磁盘缓存.而不是内存缓存机制。
3、了解在NSURLConnection上加代理。[consetDelegateQueue:[[NSOperationQueuealloc]init]]4、NSURLResponse记录的了url, mineType, exceptedContentLength, suggestedFileName等属性. 下载时用得着.
以下程序实现追踪下载百分比的下载(URLConnection自带的方法):
#import "XNDownload.h"typedef void(^ProgressBlock)(float percent);@interface XNDownload() <NSURLConnectionDataDelegate>@property (nonatomic, strong) NSMutableData *dataM;// 保存在沙盒中的文件路径@property (nonatomic, strong) NSString *cachePath;// 文件总长度@property (nonatomic, assign) long long fileLength;// 当前下载的文件长度@property (nonatomic, assign) long long currentLength;// 回调块代码@property (nonatomic, copy) ProgressBlock progress;@end@implementation XNDownload- (NSMutableData *)dataM{ if (!_dataM) { _dataM = [NSMutableData data]; } return _dataM;}- (void)downloadWithURL:(NSURL *)url progress:(void (^)(float))progress{ // 0. 记录块代码 self.progress = progress; // 1. request GET NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 2. connection NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; // 让connection支持多线程,指定代理的工作队列即可 // NSURLConnection在运行时,运行循环不负责监听代理的具体执行 [connection setDelegateQueue:[[NSOperationQueue alloc] init]]; // 3. 启动连接 [connection start];}#pragma mark - 代理方法// 1. 接收到服务器的响应,服务器执行完请求,向客户端回传数据- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ NSLog(@"%@ %lld", response.suggestedFilename, response.expectedContentLength); // 1. 保存的缓存路径 NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; self.cachePath = [cachePath stringByAppendingPathComponent:response.suggestedFilename]; // 2. 文件总长度 self.fileLength = response.expectedContentLength; // 3. 当前下载的文件长度 self.currentLength = 0; // 清空数据 [self.dataM setData:nil];}// 2. 接收数据,从服务器接收到数据- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // 拼接数据 [self.dataM appendData:data]; // 根据data的长度增加当前下载的文件长度 self.currentLength += data.length; float progress = (float)self.currentLength / self.fileLength; // 判断是否定义了块代码 if (self.progress) { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // 强制运行循环执行一次更新 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]]; self.progress(progress); }]; }}// 3. 完成接收- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"%s %@", __func__, [NSThread currentThread]); // 将dataM写入沙盒的缓存目录 // 写入数据,NSURLConnection底层实现是用磁盘做的缓存 [self.dataM writeToFile:self.cachePath atomically:YES];}// 4. 出现错误- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"%@", error.localizedDescription);}@end
二、NSURLSession实现下载
NSURLSession能实现断点续传,暂停下载等功能。
1、session提供的是开了多个线程的异步下载.
2、下载的暂停与续传: (session的代理中的方法)
*弄一个NSData变量来保存下载东西.暂停时将下载任务task清空.
*续传:将暂停时的data交给session继续下载,并将先前的data清空.
3、task一定要resume才开始执行.
#import "XNViewController.h"@interface XNViewController () <NSURLSessionDownloadDelegate>// 下载网络回话@property (nonatomic, strong) NSURLSession *session;// 下载任务@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;// 续传的二进制数据@property (nonatomic, strong) NSData *resumeData;@end@implementation XNViewController- (NSURLSession *)session{ if (!_session) { NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil]; } return _session;}- (void)viewDidLoad{ [super viewDidLoad]; [self downloadFile];}// 暂停下载任务- (IBAction)pause{ // 如果下载任务不存在,直接返回 if (self.downloadTask == nil) return; // 暂停任务(块代码中的resumeData就是当前正在下载的二进制数据) // 停止下载任务时,需要保存数据 [self.downloadTask cancelByProducingResumeData:^(NSData *resumeData) { self.resumeData = resumeData; // 清空并且释放当前的下载任务 self.downloadTask = nil; }];}- (IBAction)resume{ // 要续传的数据是否存在? if (self.resumeData == nil) return; // 建立续传的下载任务 self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData]; [self.downloadTask resume]; // 将此前记录的续传数据清空 self.resumeData = nil;}// 如果在开发中使用到缓存目录,一定要提供一个功能,“清除缓存”!/** 下载文件 */- (void)downloadFile{ NSString *urlStr = @"http://localhost/苍老师全集.rmvb"; urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url = [NSURL URLWithString:urlStr]; // (1) 代理 & 直接启动任 // 2. 启动下载任务 self.downloadTask = [self.session downloadTaskWithURL:url]; [self.downloadTask resume];}#pragma mark - 下载代理方法- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{ NSLog(@"完成 %@ %@", location, [NSThread currentThread]);}/** bytesWritten : 本次下载的字节数 totalBytesWritten : 已经下载的字节数 totalBytesExpectedToWrite : 下载总大小 */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{ float progress = (float)totalBytesWritten / totalBytesExpectedToWrite; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ //主线程中更新进度UI操作。。。。 }];}/** 续传的代理方法 */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{ NSLog(@"offset : %lld", fileOffset);}@end
出处:http://blog.csdn.net/xn4545945
3 0
- 【iOS】文件下载小记
- 【iOS】文件上传小记
- Android通过http下载文件实现小记
- ios下载文件
- IOS文件下载
- IOS文件下载
- IOS下载文件
- iOS文件下载
- 文件下载 ios
- iOS 文件分段下载
- iOS AFNetworking下载文件
- iOS 文件下载断点续传
- iOS网络文件下载
- ios 大文件下载
- iOS 文件下载
- iOS文件下载
- iOS 文件下载
- iOS文件分段下载
- android前端
- 黑马程序员_Java内省技术
- 【Android开发日记】 新浪微博API SSO授权 分享
- 7.16_A题
- C语言位运算符
- 【iOS】文件下载小记
- Cocos2d-x中2.x和3.x的粒子系统的比较
- 7.16_B题
- 7.16_C题
- Codeforces Round #256 (Div. 2)
- 海边到黄昏就的的减肥计划所见即所得圣诞节(Q977177223)
- HDU-2929-Bigger is Better
- 网络延时,抖动,丢包对voip和视频业务QoS的影响
- 应该掌握的协议