今天需要用AFNetworking实现断点续传的功能,但是在进行了一番研究之后,发现AFNetworking虽然支持下载文件的暂停和继续,但是程序重新启动后再次下载无法进行续传。网上有说可以通过AFDownloadRequestOperation这个AFNetworking的扩展库来实现重新启动后的续传,但是经过本人测试,这个库在最新的AFNetworking上会报错,无奈之下,参考他的代码,自己实现了一个,在这里分享给大家。

实现的代码如下:

 //获取已下载的文件大小
- (unsigned long long)fileSizeForPath:(NSString *)path {
signed long long fileSize = ;
NSFileManager *fileManager = [NSFileManager new]; // default is not thread safe
if ([fileManager fileExistsAtPath:path]) {
NSError *error = nil;
NSDictionary *fileDict = [fileManager attributesOfItemAtPath:path error:&error];
if (!error && fileDict) {
fileSize = [fileDict fileSize];
}
}
return fileSize;
}
//开始下载
- (void)startDownload {
NSString *downloadUrl = @"http://www.xxx.com/xxx.zip";
NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:];
NSString *downloadPath = [cacheDirectory stringByAppendingPathComponent:@"xxx.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadUrl]];
//检查文件是否已经下载了一部分
unsigned long long downloadedBytes = ;
if ([[NSFileManager defaultManager] fileExistsAtPath:downloadPath]) {
//获取已下载的文件长度
downloadedBytes = [self fileSizeForPath:downloadPath];
if (downloadedBytes > ) {
NSMutableURLRequest *mutableURLRequest = [request mutableCopy];
NSString *requestRange = [NSString stringWithFormat:@"bytes=%llu-", downloadedBytes];
[mutableURLRequest setValue:requestRange forHTTPHeaderField:@"Range"];
request = mutableURLRequest;
}
}
//不使用缓存,避免断点续传出现问题
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];
//下载请求
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
//下载路径
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:downloadPath append:YES];
//下载进度回调
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
//下载进度
float progress = ((float)totalBytesRead + downloadedBytes) / (totalBytesExpectedToRead + downloadedBytes);
}];
//成功和失败回调
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { } failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];
[operation start];
}

需要注意的是,此种写法仅适用于下载zip包,因为下载其他格式的文件有可能出现数据过多的情况。当文件已经下载完成时,再次调用该函数,无法判断文件是否已经下载完整,于是会再次下载,此时服务器会报416错,同时返回也会输出到文件中,使得文件大小异常。但是zip格式不受影响。

 
如果大家觉得对自己有帮助的话,还希望能帮顶一下,谢谢:)
转载请注明出处,谢谢!

AFNetworking实现程序重新启动时的断点续传的更多相关文章

  1. 是什么在.NET程序关闭时阻碍进程的退出?

    在平时使用软件或是.NET程序开发的过程中,我们有时会遇到程序关闭后但进程却没有退出的情况,这往往预示着代码中有问题存在,不能正确的在程序退出时停止代码执行和销毁资源.这个现象有时并不容易被察觉,但在 ...

  2. 在Linux系统如何让程序开机时自动启动

    在Linux系统如何让程序开机时自动启动      核心提示:系统的服务在开机时一般都可以自动启动,那在linux系统下如果想要程序在开机时自动启动怎么办?我们知道在 windows系统“开始”--& ...

  3. iOS 应用程序启动时要做什么

    当您的应用程序启动(无论是在前台或后台),使用您的应用程序委托application:willFinishLaunchingWithOptions:和application:didFinishLaun ...

  4. qt 单文档程序关闭时在delete ui处出现segmentation fault

    做了个显示图片的单文档程序. qt 单文档程序关闭时在delete ui处出现segmentation fault. 调试发现调用两次mainwindow析构函数. http://blog.csdn. ...

  5. VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)

    之前写的一个VC应用程序,是程序启动时就直接出现在任务栏, 窗体不出现,等用户点击任务栏图标再出现窗口.和一些防火墙什么的软件类似. 这种效果实现并不是很困难的,硬是找不到最好的.为什么呢? 首先,在 ...

  6. C/C++程序终止时执行的函数——atexit()函数详解

    很多时候我们需要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有很多种,比如main()函数运行结束.在程序的某个地方用exit()结束程序.用户通过Ctrl+C或Ctrl+break操作 ...

  7. c/c++编译时,指定程序运行时查找的动态链接库路径

    http://blog.csdn.net/tsxw24/article/details/10220735 c/c++编译时,指定程序运行时查找的动态链接库路径 分类: c/c++ linux 2013 ...

  8. Android应用程序启动时发生AndroidRuntime : ClassNotFoundException for Activity class的解决方法

    在android应用程序启动时抛出下面异常导致启动失败:07-09 17:12:35.709: ERROR/AndroidRuntime(3866): Uncaught handler: thread ...

  9. c++程序运行时的内存分配《转》

    C++中,内存分为5个区:堆.栈.自由存储区.全局/静态存储区和常量存储区. 1.栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区.通常存放局部变量.函数参数等. 2.堆:是由new分配的 ...

随机推荐

  1. linux----关于定位和查找

    1.top --查看进程2.su --临时切换用户命令[root@tomato2 ~]# sudo su gongxijun[gongxijun@tomato2 root]$ 3.whoami --- ...

  2. mint上部署lamp环境

    不得不说现在在linux mint上部署lamp很方便,比windows服务器上的asp.net的部署升级都简单. 1 安装MySql sudo apt-get install mysql-serve ...

  3. 5 echo展开

    一.(字符)展开 1.echo在标准输出中打印出他的文本 echo this is a test 输出 this is a test 2.输出通配符时,比如*代表匹配文件名的任何字符 echo * 输 ...

  4. ASP.NET Web API中的依赖注入

    什么是依赖注入 依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型如下: namespace Pattern.DI ...

  5. Jquery表单提交方式

    1.使用调用submit方法 function tes1(){ //执行判断 if(校验通过){ $("#formId").submit(); }else{ return; } } ...

  6. 使用@Controller注解为什么要配置<mvc:annotation-driven />

    自己看了官方文档,也到网上查了下,目前理解如下: <mvc:annotation-driven/>相当于注册了DefaultAnnotationHandlerMapping和Annotat ...

  7. 搜索功能demo

    代码如下: <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edg ...

  8. Writing an Hadoop MapReduce Program in Python

    In this tutorial I will describe how to write a simpleMapReduce program for Hadoop in thePython prog ...

  9. sql取年月日

    Sql Server 中一个非常强大的日期格式化函数 Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CON ...

  10. 【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】

    目录:1.潜伏者 [map] 2.Hankson的趣味题[数论]3.mayan游戏[dfs] 题目: 1. 潜伏者(spy.pas/c/cpp)[问题描述]R 国和S 国正陷入战火之中,双方都互派间谍 ...