今天需要用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. js字符串函数之substring() substr()

    substring 方法用于提取字符串中介于两个指定下标之间的字符 substring(start,end) 开始和结束的位置,从零开始的索引 参数     描述start     必需.一个非负的整 ...

  2. 《Java程序设计》实验四 实验报告

    实验四 Android开发基础 实验内容 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 ...

  3. word文档中查找和替换空格符和回车符

    空格符:^l 回车符:^p

  4. codeforces723 D. Lakes in Berland(并查集)

    题目链接:codeforces723 D. Lakes in Berland 参考博客:http://www.cnblogs.com/Geek-xiyang/p/5930245.html #inclu ...

  5. Objective-C:@property参数详解

    格式:@property(param1, param2) 类型 属性名 参数可有可无 三类参数: 1.读写属性:readwrite/readonly readwrite:产生setter\getter ...

  6. 四则运算(Android版)

    MainActivity: package com.example.demon; import android.os.Bundle; import android.app.Activity; impo ...

  7. go——beego的数据库增删改查

    一直都不理解使用go语言的时候,为什么还要自己去装beego,以为使用go便可以解决所有的问题,结果在朋友的点拨下,才意识到: go与beego的关系就好比是nodejs与thinkjs的关系,因此也 ...

  8. ThinkPHP中数据库操作返回值总结

    转自:http://www.baiwar.com/post/thinkphp-database-operations-in-the-return-value.html Thinkphp中的Think\ ...

  9. BZOJ3928 [Cerc2014] Outer space invaders

    第一眼,我勒个去...然后看到n ≤ 300的时候就2333了 首先把时间离散化,则对于一个时间的区间,可以知道中间最大的那个一定要被选出来,然后把区间分成左右两份 于是区间DP就好了,注意用左开右开 ...

  10. 在eclipse导入项目的步骤【转】

    1. Import 2. Next 3. 确定  选中copy projects into workspace    Finish 这样项目就导入进来了. 4.导入jar包 Configure Bui ...