主要是需要注意,在客服端发请求给服务器的时候,在请求头里是可以设置服务器返回的数据从哪开始,到哪结束的.

当服务器响应客户端时,是可以拿到服务器返回数据具体类型以及大小的

思路:

在接收到服务器响应时,创建一个空文件,和一个跟空文件相关联的句柄对象

然后,在接收到服务器返回的数据时,利用句柄对象,移动到文件末尾,将数据拼接到文件末尾

在接受完服务器返回的数据后,关闭句柄

#import <Foundation/Foundation.h>

@interface ZYFileDownLoad : NSObject
//所需要下载文件的远程URL(连接服务器的路径)
@property (nonatomic, strong) NSString *urlStr; //文件的存储路径
@property (nonatomic, strong) NSString *goalPath; //是否正在下载
@property (nonatomic, readonly, getter= isDownLoading) BOOL downLoading; //监听下载进度
@property (nonatomic, copy) void (^progressHandler)(double progress); //下载完成后的回调
@property (nonatomic, copy) void (^finishHandler)(); //下载失败后的回调
@property (nonatomic, copy) void (^failureHandler)(NSError *error); //开始下载
- (void)start; //暂停下载
- (void)pause; @end /*
文件一般保存在下面的地址,Documents路径下的文件需要同步,文件大的话消耗性能,tmp路径下随时会被删除
所以一般保存在Library\Caches路径下 获取此路径:
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *filepath = [caches stringByAppendingPathComponent:@"文件名.后缀名"];
*/
#import "ZYFileDownLoad.h" @interface ZYFileDownLoad() <NSURLConnectionDataDelegate>
//当前已下载的数据长度
@property (nonatomic, assign) long long currentLength; //连接对象
@property (nonatomic, strong) NSURLConnection *connection; //总的文件长度
@property (nonatomic, assign) long long totalLength; //写入文件句柄
@property (nonatomic, strong) NSFileHandle *writeHandle; @end @implementation ZYFileDownLoad
- (void)start
{
[self.urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:self.urlStr]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; //设置请求头信息,这里表示,此次数据范围是currentProgress 到文件最后(也就是只设置开头从什么地方下载)
NSString *value = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];
[request setValue:value forHTTPHeaderField:@"Range"]; self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; _downLoading = YES;
} - (void)pause
{
[self.connection cancel];
self.connection = nil;
_downLoading = NO;
} #pragma mark ----NSURLConnectionDataDelegate //请求错误(失败)的时候调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if (self.failureHandler) {
self.failureHandler(error);
}
} - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (self.totalLength) return; //当已经回复过响应了,就无需再次回复(主要用于暂停下载,再回复下载操作) //创建一个空的文件到沙盒中
NSFileManager *manager = [NSFileManager defaultManager];
[manager createFileAtPath:self.goalPath contents:nil attributes:nil]; ////创建写数据的文件句柄
self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:self.goalPath]; //获得完整文件的长度(服务器响应客户端时,会返回具体具体的文件长度)
self.totalLength = response.expectedContentLength;
} //当接受到服务器的数据就会调用(可能会被调用多次, 每次调用只会传递部分数据)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
self.currentLength += [data length]; //下载完成,累加长度 //进度
double progress = (double)self.currentLength / self.totalLength; //通过block回调,可以执行block里面的操作
if (self.progressHandler) {
self.progressHandler(progress);
} //移动文件尾部,往尾部追加数据
[self.writeHandle seekToEndOfFile];
[self.writeHandle writeData:data];
} - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//下载完毕,请客属性
self.currentLength = 0;
self.totalLength = 0; if (self.currentLength == self.totalLength) {
//下载完毕,关闭连接
[self.writeHandle closeFile];
self.writeHandle = nil;
} if (self.finishHandler) {
self.finishHandler();
}
}
@end

iOS中大文件下载(单线程下载)的更多相关文章

  1. 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】

    一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...

  2. ios的网络数据下载和json解析

    ios的网络数据下载和json解析 简介 在本文中,笔者将要给大家介绍如何使用nsurlconnection 从网上下载数据,以及解析json数据格式,以及如何显示数据和图片的异步下载显示. 涉及的知 ...

  3. IOS开发-第三方SDWebImage下载网络图片的使用

    从网络上请求图片时,没有使用第三方的话,下载会很慢,而且堵塞线程,还要自己处理多线程问题,效果还非常不明显,使用了SDWebImage这个第三方类库之后,下载图片就变的容易多了. SDWebImage ...

  4. ios背景更新和下载

    ios背景更新和下载 by 吴雪莹 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NS ...

  5. iOS之网络数据下载和JSON解析

    iOS之网络数据下载和JSON解析 简介 在本文中笔者将要给大家介绍IOS中如何利用NSURLconnection从网络上下载数据以及如何解析下载下来的JSON数据格式,以及如何显示数据和托图片的异步 ...

  6. vue打包app嵌入h5,区分app进入和android,ios显示不同的下载链接

    vue打包app嵌入h5,区分app进入和android,ios显示不同的下载链接 需求:自己app打开的登录页面不显示app下载链接.其他地方打开判断android手机的跳转到android下载页链 ...

  7. xkcd 单线程下载图片

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  8. urlretrieve 如何给文件下载设置下载进度?

    #python #xiaodeng #如何给文件下载设置下载进度? import urllib def callbackinfo(down,block,size): ''' 回调函数: down:已经 ...

  9. iOS 开发工具网页下载

    iOS 开发工具网页下载地址: https://developer.apple.com/downloads/

随机推荐

  1. 【Oracle】Oracle自定义的函数与过程

    本篇主要内容如下: 6.1 引言 6.2 创建函数 6.3 存储过程 6.3.1创建过程 6.3.2调用存储过程 6.3.3 AUTHID 6.3.4 PRAGMA AUTONOMOUS_TRANSA ...

  2. Linux中断 - 综述

    一.前言 一个合格的linux驱动工程师需要对kernel中的中断子系统有深刻的理解,只有这样,在写具体driver的时候才能: 1.正确的使用linux kernel提供的的API,例如最著名的re ...

  3. RecylerView 的使用方法

    package com.cardvalue.sys.fragment; import android.content.Intent; import android.net.Uri; import an ...

  4. js获取日期:昨天今天和明天、后天

    <html> <head> <meta http-equiv="Content-Type" content="textml; charset ...

  5. webservice复杂类型实例

    1.准备工作: 概念:SOAP(简单对象访问协议).WSDL(web服务描述语言).XML(可扩展标记语言).axis(阿帕奇可扩展交互系统) (1)     下载axis1.4,将axis1.4中的 ...

  6. SQL 正则表达式 `(user_log_acct)?+.+`

    SELECT 语句可以使用正则表达式做列选择,下面的语句查询除了 ds 和 hr 之外的所有列: SELECT `(ds|hr)?+.+` FROM test    

  7. spring中InitializingBean接口使用理解(转)

    InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: imp ...

  8. 个人用户使用genymotion 模拟器

    genymotion android模拟器速度快,比较好用.对公司使用的是要收费的,但是对个人使用还是免费的,所以个人用户还可以继续使用.使用方法 1.注册账号,填写用户名.邮箱.密码.公司类型(选g ...

  9. appium 重新启动apk

    在旧版本的appium,重新启动apk,调用startActivity方法可以随意启动一个app,并传入一个package name 和启动activity name的名称.语句如下: driver. ...

  10. Python 的黏包问题

    Client 端内的代码: #Author:BigBao #Date:2018/7/4 import socket import struct client=socket.socket(socket. ...