ASIHTTPRequest实现断点续传

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来定义头部域
  1. NSURL*url1=[NSURLURLWithString:@"下载地址";
  2. NSMutableURLRequest*request1=[NSMutableURLRequestrequestWithURL:url1];
  3. [request1setValue:@"bytes=20000-"forHTTPHeaderField:@"Range"];
  4. [request1setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
  5. NSData*returnData1=[NSURLConnectionsendSynchronousRequest:request1returningResponse:nilerror:nil];
  6. [selfwriteToFile:returnData1fileName:@"SOMEPATH"];
  7. -(void)writeToFile:(NSData*)datafileName:(NSString*)fileName
  8. {
  9. NSString*filePath=[NSStringstringWithFormat:@"%@",fileName];
  10. if([[NSFileManagerdefaultManager]fileExistsAtPath:filePath]==NO){
  11. NSLog(@"filenotexist,createit...");
  12. [[NSFileManagerdefaultManager]createFileAtPath:filePathcontents:nilattributes:nil];
  13. }else{
  14. NSLog(@"fileexist!!!");
  15. }
  16. FILE*file=fopen([fileNameUTF8String],[@"ab+"UTF8String]);
  17. if(file!=NULL){
  18. fseek(file,0,SEEK_END);
  19. }
  20. intreadSize=[datalength];
  21. fwrite((constvoid*)[databytes],readSize,1,file);
  22. fclose(file);
  23. }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值