源码0603-05-掌握-大文件下载

//  ViewController.m
//  05-掌握-大文件下载
#import "ViewController.h"
@interface ViewController () <NSURLSessionDownloadDelegate>

@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self download];
}

- (void)download
{
    // 获得NSURLSession对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];

    // 获得下载任务
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]];

    // 启动任务
    [task resume];
}

#pragma mark - <NSURLSessionDownloadDelegate>
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"didCompleteWithError");
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
    NSLog(@"didResumeAtOffset");
}

/**
 * 每当写入数据到临时文件时,就会调用一次这个方法
 * totalBytesExpectedToWrite:总大小
 * totalBytesWritten: 已经写入的大小
 * bytesWritten: 这次写入多少
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSLog(@"--------%f", 1.0 * totalBytesWritten / totalBytesExpectedToWrite);
}

/**
 *
 * 下载完毕就会调用一次这个方法
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    // 文件将来存放的真实路径
    NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    // 剪切location的临时文件到真实路径
    NSFileManager *mgr = [NSFileManager defaultManager];
    [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];
}

@end

06-掌握-大文件断点下载

//
//  ViewController.m
//  05-掌握-大文件下载
#import "ViewController.h"

@interface ViewController () <NSURLSessionDownloadDelegate>
/** 下载任务 */
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
@end

@implementation ViewController
/**
 * 开始下载
 */
- (IBAction)start:(id)sender {
    // 获得NSURLSession对象
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];

    // 获得下载任务
    self.task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]];

    // 启动任务
    [self.task resume];
}

/**
 * 暂停下载
 */
- (IBAction)pause:(id)sender {
    [self.task suspend];
}

/**
 * 继续下载
 */
- (IBAction)goOn:(id)sender {
    [self.task resume];
}

#pragma mark - <NSURLSessionDownloadDelegate>
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"didCompleteWithError");
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
    NSLog(@"didResumeAtOffset");
}

/**
 * 每当写入数据到临时文件时,就会调用一次这个方法
 * totalBytesExpectedToWrite:总大小
 * totalBytesWritten: 已经写入的大小
 * bytesWritten: 这次写入多少
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSLog(@"--------%f", 1.0 * totalBytesWritten / totalBytesExpectedToWrite);
}

/**
 *
 * 下载完毕就会调用一次这个方法
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    // 文件将来存放的真实路径
    NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    // 剪切location的临时文件到真实路径
    NSFileManager *mgr = [NSFileManager defaultManager];
    [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];
}

@end

07-掌握-大文件断点下载

//  ViewController.m
//  05-掌握-大文件下载
// resumeData的文件路径
#define XMGResumeDataFile [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"resumeData.tmp"]

#import "ViewController.h"

@interface ViewController () <NSURLSessionDownloadDelegate>
/** 下载任务 */
@property (nonatomic, strong) NSURLSessionDownloadTask *task;
/** 保存上次的下载信息 */
@property (nonatomic, strong) NSData *resumeData;

/** session */
@property (nonatomic, strong) NSURLSession *session;
@end

@implementation ViewController

- (NSURLSession *)session
{
    if (!_session) {
        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    }
    return _session;
}

//- (NSData *)resumeData
//{
//    if (!_resumeData) {
//        _resumeData = [NSData dataWithContentsOfFile:XMGResumeDataFile];
//    }
//    return _resumeData;
//}

/**
 * 开始下载
 */
- (IBAction)start:(id)sender {
//    if (self.resumeData) {
//        // 获得上次的下载任务
//        self.task = [self.session downloadTaskWithResumeData:self.resumeData];
//
//        // 将上次的临时文件放到tmp中
//
//    } else {
        // 获得下载任务
        self.task = [self.session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]];
//    }

    // 启动任务
    [self.task resume];
}

/**
 * 暂停下载
 */
- (IBAction)pause:(id)sender {
    // 一旦这个task被取消了,就无法再恢复
    [self.task cancelByProducingResumeData:^(NSData *resumeData) {
        self.resumeData = resumeData;

//
//        // 可以将resumeData写入沙盒,保存起来
//        // 下次进入程序,就可以将resumeData读取进来,继续下载
//        [resumeData writeToFile:XMGResumeDataFile atomically:YES];
//
//        // caches文件夹
//        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//
//        // 缓存文件
//        NSString *tmp = NSTemporaryDirectory();
//        NSFileManager *mgr = [NSFileManager defaultManager];
//        NSArray *subpaths = [mgr subpathsAtPath:tmp];
//        NSString *file = [tmp stringByAppendingPathComponent:[subpaths lastObject]];
//        NSString *cachesTempFile = [caches stringByAppendingPathComponent:[file lastPathComponent]];
//        [mgr moveItemAtPath:file toPath:cachesTempFile error:nil];
//
//        [@{@"tempFile" : cachesTempFile} writeToFile:[caches stringByAppendingPathComponent:@"tempFile.plist"] atomically:YES];
    }];
}

/**x
 请求这个路径:http://120.25.226.186:32812/resources/videos/minion_01.mp4
 设置请求头
 Range : 1024-2000
 */

/**
 * 继续下载
 */
- (IBAction)goOn:(id)sender {
    self.task = [self.session downloadTaskWithResumeData:self.resumeData];

    [self.task resume];
}

#pragma mark - <NSURLSessionDownloadDelegate>
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"didCompleteWithError");

    // 保存恢复数据
    self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
    NSLog(@"didResumeAtOffset");
}

/**
 * 每当写入数据到临时文件时,就会调用一次这个方法
 * totalBytesExpectedToWrite:总大小
 * totalBytesWritten: 已经写入的大小
 * bytesWritten: 这次写入多少
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSLog(@"--------%f", 1.0 * totalBytesWritten / totalBytesExpectedToWrite);
}

/**
 *
 * 下载完毕就会调用一次这个方法
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    // 文件将来存放的真实路径
    NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

    // 剪切location的临时文件到真实路径
    NSFileManager *mgr = [NSFileManager defaultManager];
    [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];
}

@end
时间: 2024-08-07 21:16:34

源码0603-05-掌握-大文件下载的相关文章

zepto源码学习-05 ajax

学习zeptoajax之前需要先脑补下,强烈推荐此文http://www.cnblogs.com/heyuquan/archive/2013/05/13/js-jquery-ajax.html 还有Aaron 的jquery源码分析系列,讲jquery的ajax的部分,当然其他也可以看,很值得学习. zepto ajax部分的设计相对简单,毕竟zepto就是轻量级的库,没有jqeury那样复杂,jquery ajax是依赖于Deferred模块的,整个代码一千多行.而zepto只有几百行,整体设

Spring AMQP 源码分析 05 - 异常处理

### 准备 ## 目标 了解 Spring AMQP Message Listener 如何处理异常 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#exception-handling> Sample code:<ht

Java入门到精通——框架篇之Spring源码分析Spring两大核心类

一.Spring核心类概述. Spring里面有两个最核心的类这是Spring实现最重要的部分. 1.DefaultListableBeanFactory 这个类位于Beans项目下的org.springframework.beans.factory.support包下. XmlBeanFactory(位于org.springframework.beans.factory.xml包)继承自DefaultListableBeanFactory,而DefaultListableBeanFactory

非常适合新手的jq/zepto源码分析05

zepto的原型  $.fn  属性: constructor //构造行数 forEach: emptyArray.forEach, //都是原生数组的函数reduce: emptyArray.reduce,push: emptyArray.push,sort: emptyArray.sort,splice: emptyArray.splice,indexOf: emptyArray.indexOf, concat //合并数组,这里还包含了合并节点集合 add //添加节点集合 is //匹

Android -- AsyncTask源码解析

1,前段时间换工作的时候,关于AsyncTask源码这个点基本上大一点的公司都会问,所以今天就和大家一起来总结总结.本来早就想写这篇文章的,当时写<Android -- 从源码解析Handle+Looper+MessageQueue机制>的时候就是想为这篇文章做铺垫的,因为AsyncTask说里面还是使用的handle,所以先就写了handle这一篇.记得15年底去美团面试的时候,面试官就问我既然存在handle为什么google还要出AsyncTask(毕竟底层还是用的handle+Exec

【React源码分析】组件通信、refs、key和ReactDOM

React源码系列文章,请多支持:React源码分析1 - 组件和对象的创建(createClass,createElement)React源码分析2 - React组件插入DOM流程React源码分析3 - React生命周期详解React源码分析4 - setState机制React源码分析5 -- 组件通信,refs,key,ReactDOMReact源码分析6 - React合成事件系统 1 组件间通信 父组件向子组件通信 React规定了明确的单向数据流,利用props将数据从父组件传

Solr4.8.0源码分析(8)之Lucene的索引文件(1)

Solr4.8.0源码分析(8)之Lucene的索引文件(1) 题记:最近有幸看到觉先大神的Lucene的博客,感觉自己之前学习的以及工作的太为肤浅,所以决定先跟随觉先大神的博客学习下Lucene的原理.由于觉先大神主要介绍的是Lucene3.X系的,那我就根据源码以及结合觉先大神的来学习下4.X系的.内容可能会有些变化,且加入下我个人的理解. http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html 一. 基本类型

SpringMVC源码剖析(二)- DispatcherServlet的前世今生

上一篇文章<SpringMVC源码剖析(一)- 从抽象和接口说起>中,我介绍了一次典型的SpringMVC请求处理过程中,相继粉墨登场的各种核心类和接口.我刻意忽略了源码中的处理细节,只列出最简单的类甚至是接口类,目的就是让大家先从最高层次的抽象意义上来审视SpringMVC这个框架:我也刻意将SpringMVC和Struts2做对比,目的是让大家看到,SpringMVC究竟吸取了Sturts2设计思想中的哪些精华,又弥补了它的哪些遗憾. DispatcherServlet作为SpringMV

linux内核源码注解

轻松学习Linux操作系统内核源码的方法 针对好多Linux 爱好者对内核很有兴趣却无从下口,本文旨在介绍一种解读linux内核源码的入门方法,而不是解说linux复杂的内核机制:一.核心源程序的文件组织:1.Linux核心源程序通常都安装在/usr/src/linux下,而且它有一个非常简单的编号约定:任何偶数的核心(例如2.0.30)都是一个稳定地发行的核心,而任何奇数的核心(例如2.1.42)都是一个开发中的核心. 本文基于稳定的2.2.5源代码,第二部分的实现平台为 RedHat Lin

从源码带看Volley的缓存机制

转载请注明出处:http://blog.csdn.net/asdzheng/article/details/45955653 磁盘缓存DiskBasedCache 如果你还不知道volley有磁盘缓存的话,请看一下我的另一篇博客请注意,Volley已默认使用磁盘缓存 DiskBasedCache内部结构 它由两部分组成,一部分是头部,一部分是内容:先得从它的内部静态类CacheHeader(缓存的头部信息)讲起,先看它的内部结构: responseHeaders; } //可以看到,头部类里包含