zoukankan      html  css  js  c++  java
  • ASIHTTPRequest实现断点续传

    http://blog.csdn.net/daiyelang/article/category/1377418

    ASIHTTPRequest可以实现断点续传。网上有一些介绍类似使用:

     
    [request setAllowResumeForFileDownloads:YES];
     
    方法的。但是它不是真正意义的断点续传。它只能让应用在下载过程中,暂停和继续。如果退出应用再进入是无效的。
     
    不过,通过ASIHTTPRequest的异步请求以及delegate还是可以实现断点续传的。
     
    本文还是以Grails编写断点续传服务器端为例。
     
    异步请求的代码:
     
     
     
    -(void) doSimpleGetBinary{ 
        NSURL *url = [NSURL URLWithString:@"http://localhost:8080/BookProto/book/image"]; 
        ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
        [request setRequestMethod:@"GET"]; 
        //[request addRequestHeader:@"Range" value:@"bytes=3-"]; 
        [request setDelegate:self]; 
        
        [request startAsynchronous]; 
    }
     
    这里设置了Delegate, 要在头文件中实现相应的protocol:
     
    @interface CFHttpDemoViewController : UIViewController<ASIProgressDelegate> {
     
    本例中使用到了delegate的如下方法。
     
    requestFinished:
     
    - (void)requestFinished:(ASIHTTPRequest *)request{ 
        NSLog(@"response status code: %i",[request responseStatusCode]); 
        NSLog(@"response content length: %@",[[request responseHeaders] objectForKey:@"Content-Length" ]); 
        NSLog(@"request finished."); 
        label.text=@"request finished."; 
    }
     
     
     
    这个方法在异步请求结束后调用。
     
    下面的方法,是当缓冲区接收到部分数据后调用,看起来是每间隔一定的毫秒,就调用一下,并传入缓冲区的NSData对象。
     
    -(void)request:(ASIHTTPRequest *)request  didReceiveData:(NSData *)data{ 
        NSLog(@"did receive data, data length: %i",[data length]); 
        
        //复制到字节数组中 
        Byte *byteData=(Byte *)malloc([data length]); 
        memcpy(byteData,[data bytes],[data length]); 
        
        for (int i=0; i<=10; i++) { 
            NSLog(@"%i: %i",i+1,byteData[i]); 
        } 
        
        free(byteData); 
        
        [request cancel]; 
        label.text=@"canceled."; 
    }
     
     
     
    运行代码,屏蔽:
     
    [request addRequestHeader:@"Range" value:@"bytes=3-"];
     
    和取消屏蔽,数据分别如下:
     
    2011-07-12 14:17:13.497 CFHttpDemo[2647:207] did receive data, data length: 10172 
    2011-07-12 14:17:13.514 CFHttpDemo[2647:207] 1: 137 
    2011-07-12 14:17:13.515 CFHttpDemo[2647:207] 2: 80 
    2011-07-12 14:17:13.516 CFHttpDemo[2647:207] 3: 78 
    2011-07-12 14:17:13.516 CFHttpDemo[2647:207] 4: 71 
    2011-07-12 14:17:13.517 CFHttpDemo[2647:207] 5: 13 
    2011-07-12 14:17:13.518 CFHttpDemo[2647:207] 6: 10 
    2011-07-12 14:17:13.518 CFHttpDemo[2647:207] 7: 26 
    2011-07-12 14:17:13.519 CFHttpDemo[2647:207] 8: 10 
    2011-07-12 14:17:13.520 CFHttpDemo[2647:207] 9: 0 
    2011-07-12 14:17:13.520 CFHttpDemo[2647:207] 10: 0 
    2011-07-12 14:17:13.521 CFHttpDemo[2647:207] 11: 0 
    2011-07-12 14:17:13.522 CFHttpDemo[2647:207] response status code: 200 
    2011-07-12 14:17:13.523 CFHttpDemo[2647:207] response content length: 10172 
    2011-07-12 14:17:13.523 CFHttpDemo[2647:207] request finished.
     
    2011-07-12 14:02:24.551 CFHttpDemo[2578:207] did receive data, data length: 10169 
    2011-07-12 14:02:24.553 CFHttpDemo[2578:207] byteData ok. 
    2011-07-12 14:02:24.554 CFHttpDemo[2578:207] 1: 71 
    2011-07-12 14:02:24.554 CFHttpDemo[2578:207] 2: 13 
    2011-07-12 14:02:24.555 CFHttpDemo[2578:207] 3: 10 
    2011-07-12 14:02:24.555 CFHttpDemo[2578:207] 4: 26 
    2011-07-12 14:02:24.556 CFHttpDemo[2578:207] 5: 10 
    2011-07-12 14:02:24.556 CFHttpDemo[2578:207] 6: 0 
    2011-07-12 14:02:24.557 CFHttpDemo[2578:207] 7: 0 
    2011-07-12 14:02:24.557 CFHttpDemo[2578:207] 8: 0 
    2011-07-12 14:02:24.558 CFHttpDemo[2578:207] 9: 13 
    2011-07-12 14:02:24.558 CFHttpDemo[2578:207] 10: 73 
    2011-07-12 14:02:24.560 CFHttpDemo[2578:207] 11: 72 
    2011-07-12 14:02:24.561 CFHttpDemo[2578:207] response status code: 206 
    2011-07-12 14:02:24.561 CFHttpDemo[2578:207] response content length: 10169 
    2011-07-12 14:02:24.562 CFHttpDemo[2578:207] request finished.
     
    2.
     
    NSUrlConnection实现断点续传的关键是自定义http request的头部的range域属性。
     
     Range头域
      Range头域可以请求实体的一个或者多个子范围。例如,
      表示头500个字节:bytes=0-499
      表示第二个500字节:bytes=500-999
      表示最后500个字节:bytes=-500
      表示500字节以后的范围:bytes=500-
      第一个和最后一个字节:bytes=0-0,-1
      同时指定几个范围:bytes=500-600,601-999
      但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。
     
    在ios中使用NSMutableURLRequest来定义头部域
    NSURL *url1=[NSURL URLWithString:@"下载地址";  
    NSMutableURLRequest* request1=[NSMutableURLRequest requestWithURL:url1];  
    [request1 setValue:@"bytes=20000-" forHTTPHeaderField:@"Range"];   
    [request1 setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];  
    NSData *returnData1 = [NSURLConnection sendSynchronousRequest:request1 returningResponse:nil error:nil];   
    [self writeToFile:returnData1 fileName:@"SOMEPATH"];  
      
      
      
      
    -(void)writeToFile:(NSData *)data fileName:(NSString *) fileName  
    {  
        NSString *filePath=[NSString stringWithFormat:@"%@",fileName];  
        if([[NSFileManager defaultManager] fileExistsAtPath:filePath] == NO){  
            NSLog(@"file not exist,create it...");  
            [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];  
        }else {  
        NSLog(@"file exist!!!");  
        }  
      
        FILE *file = fopen([fileName UTF8String], [@"ab+" UTF8String]);  
      
        if(file != NULL){  
            fseek(file, 0, SEEK_END);  
        }  
        int readSize = [data length];  
        fwrite((const void *)[data bytes], readSize, 1, file);  
        fclose(file);  
  • 相关阅读:
    android 多线程
    android调用 .net webService
    android apk程序升级
    android连数据库
    android事件
    android 服务
    android 活动
    (12)android控件-Advanced
    (11)android控件-Transitions
    (10) android控件-date
  • 原文地址:https://www.cnblogs.com/lisa090818/p/3183526.html
Copyright © 2011-2022 走看看