• 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
  • 相关阅读:
    C++ 编码转换
    获取文件扩展名
    字符串分割(C++)(转载)
    Visual Leak Detector简明使用教程
    Win32 文件拖拽
    IMAP协议命令(详细)
    CreateDirectory 创建文件夹 CC++
    编程习惯总结
    GitHub上整理的一些工具,求补充
    jquery生成qrcode二维码
  • 原文地址:https://www.cnblogs.com/goodboy-heyang/p/5191504.html
Copyright © 2020-2023  润新知