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

完整的关键代码:

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic ,assign)NSInteger totalSzie;
@property (nonatomic ,assign)NSInteger currentSzie;
@property (nonatomic, strong) NSString *fileName;
/** 文件的路径*/
@property (nonatomic ,strong) NSString *fullPath;
/** 请求对象*/
@property (nonatomic ,strong)NSURLConnection *connect;
/** 输出流*/
@property (nonatomic ,strong)NSOutputStream *stream;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@end

@implementation ViewController
#pragma mark ----------------------
#pragma mark Events
- (IBAction)downloadBtnClick:(id)sender
{
 
// [[NSFileManager defaultManager] removeItemAtPath:self.fullPath error:nil];
 
 [self download];
}
- (IBAction)cancelBtnClick:(id)sender
{
 //取消网络请求
 [self.connect cancel];
}

#pragma mark ----------------------
#pragma mark Methods
-(void)download
{
 NSLog(@"------");
 //1.确定url
 NSURL *url =[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
 
 //2.创建请求对象
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 
 //设置请求头信息,说明只需要请求该资源的一部分数据
 /*
 bytes=0-1000 表示下载0~1000的数据
 bytes=0- 表示从0开始下载直到下载完毕
 bytes=100- 表示从0开始下载直到下载完毕
 */
 NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSzie];
 [request setValue:range forHTTPHeaderField:@"Range"];
 NSLog(@"%@",range);
 
 //3.发送异步请求
 self.connect = [NSURLConnection connectionWithRequest:request delegate:self];
}

#pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
 NSLog(@"--didReceiveResponse-");
 
 //判断是否已经下载过了
 if (self.currentSzie >0) {
 return;
 }
 
 //0.获得文件的总大小
 //expectedContentLength是本次请求的数据的大小,并不是整个
 self.totalSzie = response.expectedContentLength;
 
 //1.得到文件的名称
 self.fileName = response.suggestedFilename;
 
 //2.获得文件的全路径
 //caches
 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
 
 NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];
 self.fullPath = fullPath;
 
 //3.创建输出流
 /*
 第一个参数: 写入数据的地址
 第二个参数: 表示要不要追加 断点续传肯定要追加
 */
 NSOutputStream *stream = [[NSOutputStream alloc]initToFileAtPath:fullPath append:YES];
 self.stream = stream;
 
 //4.打开数据流
 // 如果文件不存在,那么会自动创建一个空的文件
 [self.stream open];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
 //写数据
 /*
 第一个参数:要写的数据
 第二个参数:数据的长度
 */
 [self.stream write:data.bytes maxLength:data.length];
 
 
 //3.累加当前下载的数据大小
 self.currentSzie +=data.length;
 
 //4.计算文件的下载进度
 NSLog(@"%f",1.0 * self.currentSzie / self.totalSzie);
 
 self.progressView.progress = 1.0 * self.currentSzie / self.totalSzie;
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
 NSLog(@"%@",self.fullPath);
 
 //1.关闭输出流
 [self.stream close];
 
 //2.清空指针
 self.stream = nil;
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}

@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值