美文网首页
文件下载

文件下载

作者: Carden | 来源:发表于2017-05-15 17:35 被阅读10次

    初始化下载管理器

    1、遍历正下载Plist的所有字典成模型数组
    
    2、给所有下载模型赋值Task
    
    3、计算所有模型的已下载大小
    
    4、将模型数组赋值给下载管理器的临时数组
    

    添加下载

    1、判断当前url文件的下载状态(已下载、正下载、未下载)
    
    2、
    

    下载数据管理

    1、临时下载信息路径
    /Library/Caches/DownLoad/CacheList/自行车.mp4.plist
    
    2、下载完成文件路径
    /Library/Caches/DownLoad/LocalList/自行车.mp4
    
    3、FinishedPlist.plist
    [self.filelist addObject:_fileInfo];
    
    4、临时.plist文件Path->下载信息Model
    
    5、计算已下载文件的大小,方便继续断点下载
    
    

    创建请求

    • Get
    //   NSURL
    NSURL *url = [NSURL URLWithString:@""];
    //   NSURLRequest
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //   NSURLSession
    NSURLSession *session = [NSURLSession sessionWithConfiguartion:[NSURLSessionConfiguration defaultSessionConfiguration]  delegate:self  delegateQueue:[[NSOpertationQueue alloc] init]];
    //   NSURLSessionDataTask
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
         NSLog(@"%@", [NSJSONSerialazation JSONObjectWithData:data options:kNilOptions error:nil]);
    }];
    [task resume];
    
    • Post
    
    
    • Delegate
    #pragma mark --------------------------------------- <NSURLSessionDataDelegate>
    /**
     *  服务器开始响应
     */
    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
    {
        // url标识符->请求模型
        JHDownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
        
        // 请求模型->准备开始
        [info didReceiveResponse:response];
        
        // 更新本地Plist表
        [self addToLocalPlist:info];
        
        // 回调开始下载
        if([self.downloadDelegate respondsToSelector:@selector(startDownload:)]) {
            [self.downloadDelegate startDownload:info];
        }
        
        // 继续
        completionHandler(NSURLSessionResponseAllow);
    }
    
    
    /**
     *  服务器发送数据
     */
    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
    {
        JHDownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
        
        [info didReceiveData:data];
        
        // 回调更新UI
        if([self.downloadDelegate respondsToSelector:@selector(updateCellProgress:)]) {
            [self.downloadDelegate updateCellProgress:info];
        }
    }
    
    
    /**
     *  服务器结束响应
     */
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
    {
        JHDownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
        
        [info didCompleteWithError:error];
        
        [self resumeFirstWillResume];
        
        // 更新本地Plist表
        [self addToLocalPlist:info];
        
        // 回调下载完成
        if([self.downloadDelegate respondsToSelector:@selector(finishedDownload:)]) {
            [self.downloadDelegate finishedDownload:info];
        }
    }
    

    下载数据本地化

    /**
     *  获取已下载文件
     */
    -(NSArray*)getDownloadedFile
    {
        NSString *downloadedPlistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
        
        NSArray *downloadedDictArray  = [NSArray arrayWithContentsOfFile:downloadedPlistPath];
        
        NSArray *downloadedModelArray = [JHDownloadInfo mj_objectArrayWithKeyValuesArray:downloadedDictArray];
       
        
        return downloadedModelArray;
    }
    
    
    /**
     *  获取正下载文件
     */
    -(NSArray*)getDownloadingFile
    {
        NSString *downloadingPlistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadingInfo.plist"] prependCaches];
        
        NSArray *downloadingDictArray  = [NSArray arrayWithContentsOfFile:downloadingPlistPath];
        
        NSArray *downloadingModelArray = [JHDownloadInfo mj_objectArrayWithKeyValuesArray:downloadingDictArray];
        
        
        return downloadingModelArray;
    }
    
    /**
     *  删除某一个文件
     */
    -(void)delete:(JHDownloadInfo*)info{
        // 修改Plist
        [self deleteLocalPlist:info];
        
        // 删除文件
        if ([[NSFileManager defaultManager] fileExistsAtPath:info.file]) {
            [[NSFileManager defaultManager] removeItemAtPath:info.file error:nil];
        }
    }
    
    /**
     *  修改本地Plist
     */
    - (void)deleteLocalPlist:(JHDownloadInfo*)fileinfo{
        NSString *plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadingInfo.plist"] prependCaches];
        if (fileinfo.state == JHDownloadStateCompleted){
            plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
        }
            
            
        NSMutableArray *downloadingArray = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
        [downloadingArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL * _Nonnull stop) {
            NSString *url = [dict objectForKey:@"url"];
            if ([url isEqualToString:fileinfo.url]) [downloadingArray removeObject:dict];
        }];
        [downloadingArray writeToFile:plistPath atomically:YES];
    }
    
    
    /**
     *  添加本地Plist
     */
    - (void)addToLocalPlist:(JHDownloadInfo*)fileinfo
    {
        NSDictionary *fileDic = [fileinfo mj_keyValuesWithKeys:@[@"state",@"bytesWritten",@"totalBytesWritten",@"totalBytesExpectedToWrite",@"filename",@"file",@"url"]];
        
        
        NSString *plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadingInfo.plist"] prependCaches];
        if (fileinfo.state == JHDownloadStateCompleted){
            // 移除正下载
            NSMutableArray *downloadingArray = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
            [downloadingArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL * _Nonnull stop) {
                NSString *url = [dict objectForKey:@"url"];
                if ([url isEqualToString:fileinfo.url]) [downloadingArray removeObject:dict];
            }];
            [downloadingArray writeToFile:plistPath atomically:YES];
            
            // 添加新路径
            plistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
        }
        
        
        
        if([[NSFileManager defaultManager] fileExistsAtPath:plistPath]){
            NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
            [array addObject:fileDic];
            BOOL success = [array writeToFile:plistPath atomically:YES];
            NSLog(@"%@",success?@"写入成功":@"写入失败");
        }else{
            NSMutableArray *array = [[NSMutableArray alloc] init];
            [array addObject:fileDic];
            BOOL success = [array writeToFile:plistPath atomically:YES];
            NSLog(@"%@",success?@"写入成功":@"写入失败");
        }
    }
    
    

    创建任务

    • NSURLSession:NSURLSessionConfiguration、NSOperationQueue

    - (NSURLSession *)session
    {
        if (!_session) {
            // 配置
            NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
            // session
            self.session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:self.queue];
        }
        return _session;
    }
    
    - (NSOperationQueue *)queue
    {
        if (!_queue) {
            self.queue = [[NSOperationQueue alloc] init];
            self.queue.maxConcurrentOperationCount = 1;
        }
        return _queue;
    }
    
    • NSURLSessionDataDelegate

    1、开始响应

    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
    {
        // 获得下载信息
        DownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
        
        // 处理响应
        [info didReceiveResponse:response];
        
        // 继续
        completionHandler(NSURLSessionResponseAllow);
    }
    

    2、正在响应

    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
    {
        // 获得下载信息
        DownloadInfo *info = [self downloadInfoForURL:dataTask.taskDescription];
        
        // 处理数据
        [info didReceiveData:data];
    }
    

    3、结束响应

    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
    {
        // 获得下载信息
        DownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
        
        // 处理结束
        [info didCompleteWithError:error];
        
        // 恢复等待下载的
        [self resumeFirstWillResume];
    }
    

    开始任务

    • 获取下载模型

    DownloadInfo *info = [self downloadInfoForURL:url];
    
    #pragma mark - 获得下载信息
    - (DownloadInfo *)downloadInfoForURL:(NSString *)url
    {
        if (url == nil) return nil;
        
        DownloadInfo *info = [self.downloadInfoArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"url==%@", url]].firstObject;
        if (info == nil) {
            info = [[DownloadInfo alloc] init];
            info.url = url; // 设置url
            [self.downloadInfoArray addObject:info];
        }
        return info;
    }
    
    • 最大并发数Vs当前正下载

    NSArray *downloadingDownloadInfoArray = [self.downloadInfoArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"state==%d", MJDownloadStateResumed]];
    if (self.maxDownloadingCount && downloadingDownloadInfoArray.count == self.maxDownloadingCount) {
            // 等待下载
            [info willResume];
        } else {
            // 开始下载
            [info resume];
        }
    
    • 等待下载

    /** 任务 */
    @property (strong, nonatomic) NSURLSessionDataTask *task;
    
    • 开始下载

    /** 任务 */
    @property (strong, nonatomic) NSURLSessionDataTask *task;
    
    [self.task resume];
    

    初始化下载管理器

    • 下载完成

    /**
     *  服务器结束响应
     */
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
    {
        JHDownloadInfo *info = [self downloadInfoForURL:task.taskDescription];
        
        [info didCompleteWithError:error];
        
        [self resumeFirstWillResume];
        
        if (!error) [self saveDownloadFile:info];
    }
    
    /**
     *  存储已下载文件
     */
    - (void)saveDownloadFile:(JHDownloadInfo*)fileinfo
    {
        NSString *downloadedPlistPath = [[NSString stringWithFormat:@"%@/%@", JHDownloadRootDir, @"DownloadedInfo.plist"] prependCaches];
    
        NSDictionary *fileDic = [fileinfo mj_keyValues];
        
        if([[NSFileManager defaultManager] fileExistsAtPath:downloadedPlistPath]){
            NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:downloadedPlistPath];
            [array addObject:fileDic];
            BOOL success = [array writeToFile:downloadedPlistPath atomically:YES];
            NSLog(@"%@",success?@"写入成功":@"写入失败");
        }else{
            NSMutableArray *array = [[NSMutableArray alloc] init];
            [array addObject:fileDic];
            BOOL success = [array writeToFile:downloadedPlistPath atomically:YES];
            NSLog(@"%@",success?@"写入成功":@"写入失败");
        }
    }
    
    /**
     *  删除已下载的文件
     */
    - (void)deleteFinishFile:(ZFFileModel *)selectFile
    {
        [_finishedlist removeObject:selectFile];
        NSFileManager *fm = [NSFileManager defaultManager];
        NSString *path = FILE_PATH(selectFile.fileName);
        if ([fm fileExistsAtPath:path]) {
            [fm removeItemAtPath:path error:nil];
        }
        [self saveFinishedFile];
    }
    
    
    • 下载中

    /**
     * 下载文件所有信息存储为plist
     */
    - (void)saveDownloadFile:(ZFFileModel*)fileinfo
    {
        NSData *imagedata = UIImagePNGRepresentation(fileinfo.fileimage);
        NSDictionary *filedic = [NSDictionary dictionaryWithObjectsAndKeys:fileinfo.fileName,@"filename",
                                 fileinfo.fileURL,@"fileurl",
                                 fileinfo.time,@"time",
                                 fileinfo.fileSize,@"filesize",
                                 fileinfo.fileReceivedSize,@"filerecievesize",
                                 imagedata,@"fileimage",nil];
        
        NSString *plistPath = [fileinfo.tempPath stringByAppendingPathExtension:@"plist"];
        if (![filedic writeToFile:plistPath atomically:YES]) {
            NSLog(@"write plist fail");
        }
    }
    
    /*
     *  将本地的未下载完成的临时文件加载到正在下载列表里,但是不接着开始下载
     */
    - (void)loadTempfiles
    {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *error;
        NSArray *filelist = [fileManager contentsOfDirectoryAtPath:TEMP_FOLDER error:&error];
        if(!error)
        {
            NSLog(@"%@",[error description]);
        }
        NSMutableArray *filearr = [[NSMutableArray alloc]init];
        for(NSString *file in filelist) {
            NSString *filetype = [file  pathExtension];
            if([filetype isEqualToString:@"plist"])
                [filearr addObject:[self getTempfile:TEMP_PATH(file)]];
        }
        
        NSArray* arr =  [self sortbyTime:(NSArray *)filearr];
        [_filelist addObjectsFromArray:arr];
        
        [self startLoad];
    }
    
    

    相关文章

      网友评论

          本文标题:文件下载

          本文链接:https://www.haomeiwen.com/subject/xabhxxtx.html