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

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

     在实际开发中,输入输出流用的比较少,但是用起来也是很方便的。iOS开发用到的输入输出流和在Java中的输入输出流是几乎一样的,本质也是一个意思:将网络返回的数据当做流来处理。

     输入输出的理解:输入到哪里?输出到哪里?这个问题不难理解,输入输出是要站着服务器角度来思考的,下面用图来解释:

    

代码关键词:

   1、在接收到响应头的代理方法里创建输出流(根据上面的图,下载自然需要创建输出流NSOutputStream)。

    

     2、在接收数据的代理方法中写(write)数据,注意写入的是data字节(data.bytes)。

    

   3、最后在下载完毕的代理方法里关闭输出流。

   

用来做代码练习的API接口:

MP4小视频:http://120.25.226.186:32812/resources/videos/minion_01.mp4

完整的关键代码:

  1 #import "ViewController.h"
  2
  3 @interface ViewController ()
  4 @property (nonatomic ,assign)NSInteger totalSzie;
  5 @property (nonatomic ,assign)NSInteger currentSzie;
  6 @property (nonatomic, strong) NSString *fileName;
  7 /** 文件的路径*/
  8 @property (nonatomic ,strong) NSString *fullPath;
  9 /** 请求对象*/
 10 @property (nonatomic ,strong)NSURLConnection *connect;
 11 /** 输出流*/
 12 @property (nonatomic ,strong)NSOutputStream *stream;
 13 @property (weak, nonatomic) IBOutlet UIProgressView *progressView;
 14 @end
 15
 16 @implementation ViewController
 17 #pragma mark ----------------------
 18 #pragma mark Events
 19 - (IBAction)downloadBtnClick:(id)sender
 20 {
 21
 22 //    [[NSFileManager defaultManager] removeItemAtPath:self.fullPath error:nil];
 23
 24     [self download];
 25 }
 26 - (IBAction)cancelBtnClick:(id)sender
 27 {
 28     //取消网络请求
 29     [self.connect cancel];
 30 }
 31
 32 #pragma mark ----------------------
 33 #pragma mark Methods
 34 -(void)download
 35 {
 36     NSLog(@"------");
 37     //1.确定url
 38     NSURL *url =[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
 39
 40     //2.创建请求对象
 41     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 42
 43     //设置请求头信息,说明只需要请求该资源的一部分数据
 44     /*
 45      bytes=0-1000 表示下载0~1000的数据
 46      bytes=0-     表示从0开始下载直到下载完毕
 47      bytes=100-   表示从0开始下载直到下载完毕
 48      */
 49     NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSzie];
 50     [request setValue:range forHTTPHeaderField:@"Range"];
 51     NSLog(@"%@",range);
 52
 53     //3.发送异步请求
 54     self.connect = [NSURLConnection connectionWithRequest:request delegate:self];
 55 }
 56
 57 #pragma mark ----------------------
 58 #pragma mark NSURLConnectionDataDelegate
 59 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
 60 {
 61     NSLog(@"--didReceiveResponse-");
 62
 63     //判断是否已经下载过了
 64     if (self.currentSzie >0) {
 65         return;
 66     }
 67
 68     //0.获得文件的总大小
 69     //expectedContentLength是本次请求的数据的大小,并不是整个
 70     self.totalSzie = response.expectedContentLength;
 71
 72     //1.得到文件的名称
 73     self.fileName = response.suggestedFilename;
 74
 75     //2.获得文件的全路径
 76     //caches
 77     NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
 78
 79     NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];
 80     self.fullPath = fullPath;
 81
 82     //3.创建输出流
 83     /*
 84      第一个参数: 写入数据的地址
 85      第二个参数: 表示要不要追加 断点续传肯定要追加
 86      */
 87     NSOutputStream *stream = [[NSOutputStream alloc]initToFileAtPath:fullPath append:YES];
 88     self.stream = stream;
 89
 90     //4.打开数据流
 91     // 如果文件不存在,那么会自动创建一个空的文件
 92     [self.stream open];
 93 }
 94
 95 -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
 96 {
 97     //写数据
 98     /*
 99      第一个参数:要写的数据
100      第二个参数:数据的长度
101      */
102     [self.stream write:data.bytes maxLength:data.length];
103
104
105     //3.累加当前下载的数据大小
106     self.currentSzie +=data.length;
107
108     //4.计算文件的下载进度
109     NSLog(@"%f",1.0 *  self.currentSzie / self.totalSzie);
110
111     self.progressView.progress = 1.0 *  self.currentSzie / self.totalSzie;
112 }
113
114 -(void)connectionDidFinishLoading:(NSURLConnection *)connection
115 {
116     NSLog(@"%@",self.fullPath);
117
118     //1.关闭输出流
119     [self.stream close];
120
121     //2.清空指针
122     self.stream = nil;
123 }
124
125 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
126 {
127 }
128
129 @end
时间: 2024-12-09 22:58:26

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

iOS开发之网络编程--使用NSURLConnection实现大文件下载

主要思路(实现下载数据分段写入缓存中) 1.使用NSURLConnectionDataDelegate以及代理方法.2.在成功获取响应的代理方法中,获得沙盒全路径,并在该路径下创建空文件和文件句柄.3.在获取data的代理方法中,先设置句柄在沙盒全路径文件末尾,然后通过句柄写入data数据.4.在文件下载完的代理方法中,关闭句柄同时设置句柄引用为nil释放句柄和指针. 使用句柄的思路图(红色的箭头表示句柄,灰色的箭头表示移动的路径): 代码关键词: 类:NSFileHandle的方法 1.fil

iOS开发之网络编程--5、NSURLSessionUploadTask+NSURLSessionDataDelegate代理上传

前言:关于NSURLSession的主要内容快到尾声了,这里就讲讲文件上传.关于文件上传当然就要使用NSURLSessionUploadTask,这里直接讲解常用的会和代理NSURLSessionDataDelegate一起搭配实现文件上传功能.另外,下面使用的文件上传思路是和NSURLConnection中本人之前的随笔<iOS开发之网络编程--使用NSURLConnection实现文件上传>提到的上传思路是一样的,都是要将请求信息拼接起来,然后传入到请求里进行上传.这个拼接过程是必要的,但

IOS开发之网络编程(请求数据和断点续传)

IOS开发中网络编程应用场景:JSON数据获取,网络数据的下载. 一:请求JSON数据一般用异步请求的方式,如果用同步请求,则会造成IOS界面的执行过程阻塞,即界面部分在请求数据的过程中必须等待数据加载完毕. JSON数据的获取步骤: 1.设置网络地址的字符串:NSString *URLString = @"http://www.baidu.com"; 2.创建URL:NSURL *URL = [NSURL URLWithString:URLString]; 3.创建请求:NSURLR

iOS开发之网络编程--2、NSURLSessionDownloadTask文件下载

本文内容大纲: 1.回顾NSURLSessionTask 2.NSURLSessionDownloadTask大文件之block下载 3.NSURLSessionDownloadTask大文件之代理方法下载 4.NSURLSessionDownloadTask大文件之代理方法实现断点续传下载 前言:如果读者是第一次阅读或者是学习关于本篇要介绍的NSURLSession的知识,最好先阅读本人前篇<iOS开发之网络编程--1.NSURLSession的基本使用>然后再学习本篇比较好. 1.回顾NS

使用NSURLConnection实现大文件断点下载

使用NSURLConnection实现大文件断点下载 由于是实现大文件的断点下载,不是下载一般图片什么的.在设计这个类的时候本身就不会考虑把下载的文件缓存到内存中,而是直接写到文件系统. 要实现断点下载,需要满足1个条件,那就是,必须要服务器支持断点下载. 实现的思路是这样子的: 1.  第一次会获取到被下载文件的总大小(服务器提供这个值) 下载文件总大小 = 期望从服务器获取文件的大小 + 本地已经下载的文件的大小 2.  设置请求的缓存策略为不会读取本地中已经缓存的数据(NSURLReque

iOS开发之网络编程--XCode7 更新以来需要手动设置的内容

XCode7 更新以来,默认是不允许加载一些http网络请求,是因为现在网络大部分使用更安全的https协议头. 所以,iOS网络编程如果出现请求无效,事先考虑是否设置一下了以下操作:

iOS开发之网络编程--6、NSURLSessionConfiguration笔记

NSURLSessionConfiguration对象用于初始化NSURLSession对象. 展开请求级别中与NSMutableURLRequest相关的可供选择的方案,我们可以看到NSURLSessionConfiguration对于会话如何产生请求,提供了相当多的控制和灵活性.从网络访问性能,到cookie,安全性,缓存策略,自定义协议,启动事件设置,以及用于移动设备优化的几个新属性,你会发现你一直在寻找的,正是NSURLSessionConfiguration. 会话在初始化时复制它们的

iOS开发之网络编程--1、NSURLSession的基本使用

前言:学习NSURLSession的使用之前,先学习一篇关于NSURLSession的好文章<From NSURLConnection to NSURLSession>或者是国内的译文<从 NSURLConnection 到 NSURLSession>,或者不用学习本人的博客园笔记直接学习<从 NSURLConnection 到 NSURLSession>也是可以的,这篇对NSURLSession的使用有着挺详细的论述.但是本文先粗略介绍一下NSURLSession的基

iOS开发之网络编程--获取文件的MIMEType

前言:有时候我们需要获取文件的MIMEType的信息,下面就介绍关于获取MIMEType的方法. 1.直接百度搜索关键字"MIMEType",你会找到,然后查吧: 2.用代码获取文件的MIMEType信息: 1 #import "GetMIMEType.h" 2 3 #import <MobileCoreServices/MobileCoreServices.h> 4 5 @implementation GetMIMEType 6 7 #pragma m