多线程断点下载
来源:互联网 发布:windows损坏文件 编辑:程序博客网 时间:2024/05/20 19:19
1.文件下载类(父类)
//// FileDownloader.h// 文件下载器// 一个FileDownloader下载一个文件#import <Foundation/Foundation.h>@interface FileDownloader : NSObject{ BOOL _downloading;}/** * 所需要下载文件的远程URL(连接服务器的路径) */@property (nonatomic, copy) NSString *url;/** * 文件的存储路径(文件下载到什么地方) */@property (nonatomic, copy) NSString *destPath;/** * 是否正在下载(有没有在下载, 只有下载器内部才知道) */@property (nonatomic, readonly, getter = isDownloading) BOOL downloading;/** * 用来监听下载进度 */@property (nonatomic, copy) void (^progressHandler)(double progress);/** * 开始(恢复)下载 */- (void)start;/** * 暂停下载 */- (void)pause;@end
//// FileDownloader.m// 文件下载器//#import "FileDownloader.h"@implementation FileDownloader@end2.单点下载类
//// FileSingleDownloader.h#import "FileDownloader.h"@interface FileSingleDownloader : FileDownloader/** * 下载的范围(开始位置) */@property(nonatomic,assign)long long begin;/** * 下载的范围(结束位置) */@property(nonatomic,assign)long long end;@end
//// FileSingleDownloader.m#import "FileSingleDownloader.h"@interface FileSingleDownloader() <NSURLConnectionDataDelegate>/** * 连接对象 */@property(nonatomic,strong)NSURLConnection *conn;/** * 写数据的文件句柄 */@property(nonatomic,strong)NSFileHandle *writeHandle;/** * 当前已下载的数据的长度 */@property(nonatomic,assign)long long currentLength;@end@implementation FileSingleDownloader- (NSFileHandle *)writeHandle{ if (!_writeHandle) { _writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.destPath]; } return _writeHandle;}/** * 开始(恢复)下载 */- (void)start{ NSURL *url = [NSURL URLWithString:self.url]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //设置请求头 NSString *value = [NSString stringWithFormat:@"bytes=%lld-%lld",self.begin+self.currentLength,self.end]; [request setValue:value forHTTPHeaderField:@"Range"]; self.conn = [NSURLConnection connectionWithRequest:request delegate:self]; _downloading = YES;}/** * 暂停 */- (void)pause{ [self.conn cancel]; self.conn = nil; _downloading = NO;}#pragma mark - NSURLConnectionDataDelegate/** * 1.当接受到服务器的响应的就会调用 */- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{}/** * 2.当接受到服务器返回的数据就会调用(可能会被调用多次,每次只会传递部分数据) */- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //移到到文件的尾部 [self.writeHandle seekToFileOffset:self.begin + self.currentLength]; //从当前移动的位置(文件尾部)开始写入数据 [self.writeHandle writeData:data]; //2.累计已下载的数据的长度 self.currentLength += data.length; //打印下载进度 double progress = (double)self.currentLength / (self.end-self.begin); if (self.progressHandler) { self.progressHandler(progress); }}/** * 3.当服务器的数据接受完毕后就会调用 */- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ //清空属性值 self.currentLength = 0; //关闭连接(不再输入数据到文件中) [self.writeHandle closeFile]; self.writeHandle = nil;}/** * 请求失败的时候调用(请求超时、断网、没有网。一般都是客户端错误) */- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{}@end3.多点下载
//// FileMultiDownloader.h// 文件下载// 多线程下载器(利用FileMultiDownloader能开启多个线程同时下载一个文件)// 一个多线程下载器 只 下载一个文件#import "FileDownloader.h"@interface FileMultiDownloader : FileDownloader@end
//// FileMultiDownloader.m#import "FileMultiDownloader.h"#import "FileSingleDownloader.h"#define MaxDownloadCount 3@interface FileMultiDownloader()@property(nonatomic,strong)NSMutableArray *singleDownloaders;@property(nonatomic,assign)long long totalLength;@end@implementation FileMultiDownloader/** * 获得要下载的文件的大小 */- (void)getFilesize{ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]]; request.HTTPMethod = @"HEAD"; NSURLResponse *response = nil; [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; self.totalLength = response.expectedContentLength;}- (NSMutableArray *)singleDownloaders{ if (!_singleDownloaders) { _singleDownloaders = [NSMutableArray array]; //获取文件大小 [self getFilesize]; //每条线程的下载量 long long size = 0; if (self.totalLength % MaxDownloadCount == 0) { size = self.totalLength / MaxDownloadCount; }else{ size = self.totalLength / MaxDownloadCount + 1; } //创建N个下载器 for (int i=0; i<MaxDownloadCount; i++) { FileSingleDownloader *singleDownloader = [[FileSingleDownloader alloc] init]; singleDownloader.url = self.url; singleDownloader.destPath = self.destPath; singleDownloader.begin = i * size; singleDownloader.end = singleDownloader.begin + size - 1; singleDownloader.progressHandler = ^(double progress){ //打印下载进度// NSLog(@"%d----%f",i,progress); }; [_singleDownloaders addObject:singleDownloader]; } //创建一个跟服务器文件等大小的临时文件 [[NSFileManager defaultManager] createFileAtPath:self.destPath contents:nil attributes:nil]; //让self.destPath文件的长度是 self.totalLength NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.destPath]; [handle truncateFileAtOffset:self.totalLength]; } return _singleDownloaders;}/** * 开始(恢复)下载 */- (void)start{ [self.singleDownloaders makeObjectsPerformSelector:@selector(start)]; _downloading = YES;}/** * 暂停 */- (void)pause{ [self.singleDownloaders makeObjectsPerformSelector:@selector(pause)]; _downloading = NO;}@end4.控制器调用
#import "ViewController.h"#import "FileMultiDownloader.h"@interface ViewController ()//下载器@property(nonatomic,strong)FileMultiDownloader *fileMultiDownloader;@end@implementation ViewController- (FileMultiDownloader *)fileDownloader{ if (!_fileMultiDownloader) { _fileMultiDownloader = [[FileMultiDownloader alloc] init]; //需要下载的远程文件URL _fileMultiDownloader.url = @"https://xxxx.com/images.zip"; //文件保存到什么地方 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]; NSString *filepath = [caches stringByAppendingPathComponent:@"images.zip"]; _fileMultiDownloader.destPath = filepath; } return _fileMultiDownloader;}- (void)viewDidLoad { [super viewDidLoad];}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //开始下载 [self.fileMultiDownloader start];}@end
0 0
- 多线程下载断点下载
- 多线程下载,断点下载
- java 多线程断点下载
- 网络多线程断点下载
- 网络多线程断点下载
- 网络多线程断点下载
- android多线程断点下载
- 多线程断点下载原理
- 多线程断点下载文件
- java 多线程断点下载
- android 多线程断点下载
- android多线程断点下载
- 多线程断点下载器
- Java---多线程断点下载
- Java--多线程断点下载
- 断点多线程下载
- android多线程断点下载
- android,多线程断点下载
- 第七届河南省赛 zzuoj 10403: D.山区修路 (DP转换&&技巧)
- Sublime Text 3插件安装
- mina 心跳机制
- 【iOS】OC总结
- lua模块的几种实现方式
- 多线程断点下载
- android post提交数据
- Android studio提交SVN需要忽略的文件
- 设计模式—装饰器模式(Decorator)
- leetcode 做题记录
- Jetty实战之 安装 运行 部署
- ORACLE内存管理简述1
- php高级函数【递归函数】
- 记录下过年要写的博客