* 移动客户端在和服务器交互的时候,上传和下载使用十分广泛。

* 在我们下载文件的时候,我们在点击暂停的时候可以暂停下载,点击下载的时候可以继续下载,这个功能如何实现?

* 下载进度条如何显示?

先大概叙述一下断点下载的原理:

* 首先先判断要判断要下载的文件在本地沙盒中是否存在。

* 如果存在的话,要判断下载文件的长度。

* 假设文件长度是500,我们发起下载请求的时候应该从500开始。

* 点击暂停下载,应该将链接断掉。

* 再次点击下载的时候,根据下载文件长度,继续下载。

下面与代码结合起来叙述具体的实现:

* 假设我们要下载的文件在服务器的路径为:http://localhost:8080:down/xcode_6.dmg;

* 我们将要下载的文件方法本地沙盒中。文件命名为:xcode.dmg.

* 获取文件保存路径的代码:(折叠)

  1. -(NSString *)getFilePath
  2. {
  3. NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[];
  4. NSString *filePath = [documentsPath stringByAppendingPathComponent:@"xcode.dmg"];
  5. return filePath;
  6. }

下载文件保存路径

* 因为下载的文件比较大,我们需要采取异步请求网络。

* 异步请求网络常用的有四个代理方法。

* 发起网络请求下载。(下载起始点为上次暂停点,判断上次暂停位置方法是,获取文件属性,从属性中可以查看文件长度,请求点为该长度后面的内容)

* 假设向获取某个字节的内容,可以使用:

    //bytes = 0-499 请求前500个字节的内容

    //bytes = 500- 请求500字节之后的内容

    //bytes = 500-1000 请求资源中某一范围的内容

    //bytes = 0-1,499-500 请求多个范围之间的内容

* 进度条过去文件下载进度,可以使用已经下载的文件的字节数/文件的总字节数。

下面为具体的代码段,里面有详细的注释:

  1. #import <UIKit/UIKit.h>
  2.  
  3. @interface ViewController : UIViewController<NSURLConnectionDataDelegate>
  4. {
  5. //进度条变量,显示文件下载进度
  6. IBOutlet UIProgressView *_progress;
  7. //文件处理,将下载的文件写入本地沙盒
  8. NSFileHandle *_fileHandle;
  9. //url连接,点解暂停,取消连接,点击下载,开始下载
  10. NSURLConnection *_connection;
  11. //已经接收数据大小
  12. long long _receiveSize;
  13. //文件总共的大小
  14. long long _totalSize;
  15. }
  16.  
  17. //下载按钮点击响应函数
  18. - (IBAction)download:(id)sender;
  19. //暂停按钮点击响应函数
  20. - (IBAction)pause:(id)sender;
  21.  
  22. @end
  1. - (IBAction)download:(id)sender
  2. {
  3. //文件的路径
  4. NSString *string = @"http://localhost:8080/down/xcode_6.dmg";
  5. //文件的路径转化为url
  6. NSURL *url = [NSURL URLWithString:string];
  7. //创建可变请求
  8. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  9. //判断沙盒路径下有没有这个文件,YES表示这个文件已经下载,NO表示还没有下载
  10. if ([[NSFileManager defaultManager] fileExistsAtPath:[self getFilePath]] == YES)
  11. {
  12.  
  13. //根据文件的属性,获取之前下载数据量是多少
  14. NSDictionary *fileDic = [[NSFileManager defaultManager]attributesOfItemAtPath:[self getFilePath] error:nil];
  15. //文件的长度就是已经下载的数据量
  16. _receiveSize = [fileDic[NSFileSize] longLongValue];
  17. //设置Range,从Range之后的内容开始下载
  18. //bytes = 0-499 请求前500个字节的内容
  19. //bytes = 500- 请求500字节之后的内容
  20. //bytes = 500-1000 请求资源中某一范围的内容
  21. //bytes = 0-1,499-500 请求多个范围之间的内容
  22. NSString *bytes = [NSString stringWithFormat:@"bytes=%lld-",_receiveSize];
  23. [request setValue:bytes forHTTPHeaderField:@"Range"];
  24.  
  25. }
  26. //发起异步请求,文件比较法,使用异步请求
  27. _connection = [NSURLConnection connectionWithRequest:request delegate:self];
  28. }
  29. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
  30. {
  31. //分析响应头
  32. NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
  33. //获取响应头,是一个字典
  34. NSDictionary *responseHeader = httpResponse.allHeaderFields;
  35. //接收文件总的大小等于已经下载的数据量,加上为下载的数据量
  36. _totalSize = _receiveSize + [responseHeader[@"Content-Length"] longLongValue];
  37. //创建文件管理类
  38. NSFileManager *fileManager = [NSFileManager defaultManager];
  39. //沙盒中不存在要下载的文件,就创建该文件
  40. if ([fileManager fileExistsAtPath:[self getFilePath]] == NO)
  41. {
  42. [fileManager createFileAtPath:[self getFilePath] contents:nil attributes:nil];
  43. }
  44. //根据路径写入文件
  45. _fileHandle = [NSFileHandle fileHandleForWritingAtPath:[self getFilePath]];
  46. }
  47.  
  48. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  49. {
  50. //文件比较大的话,需要多次写入,写入的话,需要将光标定位到结尾
  51. [_fileHandle seekToEndOfFile];
  52. //将数据写入到文件
  53. [_fileHandle writeData:data];
  54. //最新接收到数据的大小等于文件中已有的数据,加上刚刚下载的数据量
  55. _receiveSize = _receiveSize + data.length;
  56. //计算进度
  57. float jundu = (float)_receiveSize / _totalSize;
  58. //使用进度条来表示进度
  59. _progress.progress = jundu;
  60. }
  61.  
  62. - (void)connectionDidFinishLoading:(NSURLConnection *)connection
  63. {
  64. //文件完成传输,关闭文件管理
  65. [_fileHandle closeFile];
  66. }
  67.  
  68. - (IBAction)pause:(id)sender
  69. {
  70. //点击暂停,取消请求连接
  71. [_connection cancel];
  72. _connection = nil;
  73. }
  74.  
  75. -(NSString *)getFilePath
  76. {
  77. NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
  78. NSString *filePath = [documentsPath stringByAppendingPathComponent:@"xcode.dmg"];
  79. return filePath;
  80. }

iOS-文件断点续传的更多相关文章

  1. iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄

    前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传.    在实际开发中,输入输出流用的比较少,但 ...

  2. iOS——文件操作NSFileManager (创建、删除,复制,粘贴)

    iOS——文件操作NSFileManager (创建.删除,复制,粘贴)       iOS的沙盒机制,应用只能访问自己应用目录下的文件.iOS不像android,没有SD卡概念,不能直接访问图像.视 ...

  3. IOS文件操作的两种方式:NSFileManager操作和流操作

    1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...

  4. 文件断点续传原理与实现—— ESFramework 通信框架4.0 进阶(12)

    在ESFramework通信框架 4.0 快速上手(13) -- 文件传送,如此简单一文的详细介绍和ESFramework通信框架 4.0 快速上手(14) -- 聊天系统Demo,增加文件传送功能( ...

  5. IOS 文件解析

    import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...

  6. iOS文件处理类

    iOS文件处理类 这是一个用来简化iOS中关于文件操作的一个类,所有方法都为类方法. Source File.h // // File.h // FileManager // // http://ho ...

  7. iOS文件上传文件URL错误Invalid parameter not satisfying: fileURL'

    一:iOS文件上传提示URL错误 Invalid parameter not satisfying: fileURL' 二:解决方法: NSString *imagePath = [[NSBundle ...

  8. IOS 文件夹结构

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/MyGameZone/article/details/24494765 IOS文件夹结构 说明 这些仅 ...

  9. js -- fileData 实现文件断点续传

    前端实现文件的断点续传 一.一些知识准备 断点续传,既然有断,那就应该有文件分割的过程,一段一段的传. 以前文件无法分割,但随着HTML5新特性的引入,类似普通字符串.数组的分割,我们可以可以使用sl ...

  10. php实现大文件断点续传下载实例

    php实现大文件断点续传下载实例,看完你就知道超过100M以上的大文件如何断点传输了,这个功能还是比较经典实用的,毕竟大文件上传功能经常用得到. require_once('download.clas ...

随机推荐

  1. MySQL基础教程——创建数据库并插入数据

    本节将介绍 MySQL 新建数据库,新建表,插入数据以及基本数据类型的相关知识.本节实验将创建一个名为 mysql_shiyan 的数据库,其中有两张表 employee和 department. 1 ...

  2. FiraCode 字体 => 箭头函数变成 整体 还有 等于 不等于

    https://github.com/tonsky/FiraCode Enable in Settings → Editor → Color Scheme → Color Scheme Font →  ...

  3. String中关于BeanFactory

    org.springframework.beans及org.springframework.context包是Spring IoC容器的基础.BeanFactory提供的高级配置机制,使得管理任何性质 ...

  4. RabbitMQ Server的安装、配置及常用命令

    首先需要安装Erlang环境: http://www.rabbitmq.com/server.html 下载RabbitMQ Server的windows安装包并安装到D盘下: http://www. ...

  5. cesium 基于天地图服务 完成底图标注渲染加切换

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 【转】LDA-linear discriminant analysis

    分类问题也可以用降维来理解,比如一个D维的数据点x,我们可以采用下面的映射进行线性的降维, y=θTx 在计算出y后,就可以选择一个阈值h,来进行分类.正如我们在前面的PCA模型中看到的,降维会有信息 ...

  7. 使用el-checkbox实现全选,点击失效没有反应

    最近在公司接收到了一个需求,给收藏夹的书籍添加批量.全选删除实现思路:点击全选改变item的checked,改变item的checked,重新便利一下所有item的checked来改变全选的selec ...

  8. 如何使用 HTML5 的picture元素处理响应式图片

    来自: http://www.w3cplus.com/html5/quick-tip-how-to-use-html5-picture-for-responsive-images.html 图片在响应 ...

  9. ProC第二弹

    一.提要 上文简单介绍了Windows下ProC配置开发,这次我们使用Linux平台再次配置Oracle ProC开发环境(RedHat Linux 9 + Oracle 92).    <OR ...

  10. LeetCode(206) Reverse Linked List

    题目 Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed eithe ...