一:小文件下载

#import "ViewController.h"@interface ViewController ()<NSURLConnectionDataDelegate>
/** 注释 */
@property (nonatomic, strong) NSMutableData *fileData;
@property (nonatomic, assign) NSInteger totalSize;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end@implementation ViewController-(NSMutableData *)fileData
{if (_fileData == nil) {_fileData = [NSMutableData data];}return _fileData;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{[self download3];
}//耗时操作[NSData dataWithContentsOfURL:url]
-(void)download1
{//1.urlNSURL *url = [NSURL URLWithString:@"http://img5.imgtn.bdimg.com/it/u=1915764121,2488815998&fm=21&gp=0.jpg"];//2.下载二进制数据NSData *data = [NSData dataWithContentsOfURL:url];//3.转换UIImage *image = [UIImage imageWithData:data];
}//1.无法监听进度
//2.内存飙升
-(void)download2
{//1.url// NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.发送请求[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {//4.转换
//        UIImage *image = [UIImage imageWithData:data];
//
//        self.imageView.image = image;//NSLog(@"%@",connectionError);//4.写数据到沙盒中NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];[data writeToFile:fullPath atomically:YES];}];
}//内存飙升
-(void)download3
{//1.url// NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.发送请求[[NSURLConnection alloc]initWithRequest:request delegate:self];
}#pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
/***  1:当接收到服务器响应的时候调用:只调用一次**/
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{NSLog(@"didReceiveResponse");//得到文件的总大小(本次请求的文件数据的总大小)self.totalSize = response.expectedContentLength;
}/***    2:当下载数据的时候调用,可能被调用多次:在此方法内部有时需要拼接data,也可以在此方法中获得下载的进度**/
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{// NSLog(@"%zd",data.length);
    [self.fileData appendData:data];//进度=已经下载/文件的总大小NSLog(@"%f",1.0 * self.fileData.length /self.totalSize);
}/*** 3:下载失败的时候的调用**/
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}/***    4:下载成功的时候调用**/
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{NSLog(@"connectionDidFinishLoading");//4.写数据到沙盒中NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];[self.fileData writeToFile:fullPath atomically:YES];NSLog(@"%@",fullPath);
}/***    三种方法的区别:1:耗时操作[NSData dataWithContentsOfURL:url]  2:sendAsynchronousRequest,无法监听进度  3:可以进行进度的监听,以及对下载完成后数据的处理*/
@end

(1)第一种方式(NSData)

```objc

//使用NSDta直接加载网络上的url资源(不考虑线程)

-(void)dataDownload

{

//1.确定资源路径

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];

//2.根据URL加载对应的资源

NSData *data = [NSData dataWithContentsOfURL:url];

//3.转换并显示数据

UIImage *image = [UIImage imageWithData:data];

self.imageView.image = image;

}

```

(2)第二种方式(NSURLConnection-sendAsync)

```objc

//使用NSURLConnection发送异步请求下载文件资源

-(void)connectDownload

{

//1.确定请求路径

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];

//2.创建请求对象

NSURLRequest *request = [NSURLRequest requestWithURL:url];

//3.使用NSURLConnection发送一个异步请求

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

//4.拿到并处理数据

UIImage *image = [UIImage imageWithData:data];

self.imageView.image = image;

}];

}

```

(3)第三种方式(NSURLConnection-delegate)

```objc

//使用NSURLConnection设置代理发送异步请求的方式下载文件

-(void)connectionDelegateDownload

{

//1.确定请求路径

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

//2.创建请求对象

NSURLRequest *request = [NSURLRequest requestWithURL:url];

//3.使用NSURLConnection设置代理并发送异步请求

[NSURLConnection connectionWithRequest:request delegate:self];

}

#pragma mark--NSURLConnectionDataDelegate

//当接收到服务器响应的时候调用,该方法只会调用一次

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

//创建一个容器,用来接收服务器返回的数据

self.fileData = [NSMutableData data];

//获得当前要下载文件的总大小(通过响应头得到)

NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

self.totalLength = res.expectedContentLength;

NSLog(@"%zd",self.totalLength);

//拿到服务器端推荐的文件名称

self.fileName = res.suggestedFilename;

}

//当接收到服务器返回的数据时会调用

//该方法可能会被调用多次

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

//    NSLog(@"%s",__func__);

//拼接每次下载的数据

[self.fileData appendData:data];

//计算当前下载进度并刷新UI显示

self.currentLength = self.fileData.length;

NSLog(@"%f",1.0* self.currentLength/self.totalLength);

self.progressView.progress = 1.0* self.currentLength/self.totalLength;

}

//当网络请求结束之后调用

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

{

//文件下载完毕把接受到的文件数据写入到沙盒中保存

//1.确定要保存文件的全路径

//caches文件夹路径

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];

//2.写数据到文件中

[self.fileData writeToFile:fullPath atomically:YES];

NSLog(@"%@",fullPath);

}

//当请求失败的时候调用该方法

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

NSLog(@"%s",__func__);

}

```

二:大文件下载

#import "ViewController.h"@interface ViewController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;@property (nonatomic, assign) NSInteger totalSize;
@property (nonatomic, assign) NSInteger currentSize;
/** 文件句柄*/
@property (nonatomic, strong)NSFileHandle *handle;
/** 沙盒路径 */
@property (nonatomic, strong) NSString *fullPath;
@end@implementation ViewController
/*** 1:大文件下载的时候,不断的拼接二进制数据,此时会导致内存的飙升,所以此时应该用文件句柄去写文件,创建一个空文件夹,创建文件句柄对象,将下载的文件一点一点拼接到空文件夹内。在文件下载完毕后,要关闭文件句柄,并设为nil空值**/
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{[self download3];
}//内存飙升
-(void)download3
{//1.url// NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];//2.创建请求对象NSURLRequest *request = [NSURLRequest requestWithURL:url];//3.发送请求[[NSURLConnection alloc]initWithRequest:request delegate:self];
}#pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{NSLog(@"didReceiveResponse");//1.得到文件的总大小(本次请求的文件数据的总大小)self.totalSize = response.expectedContentLength;//2.写数据到沙盒中self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];//3.创建一个空的文件
    [[NSFileManager defaultManager] createFileAtPath:self.fullPath contents:nil attributes:nil];//4.创建文件句柄(指针)self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
}-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{//1.移动文件句柄到数据的末尾
    [self.handle seekToEndOfFile];//2.写数据
    [self.handle writeData:data];//3.获得进度self.currentSize += data.length;//进度=已经下载/文件的总大小NSLog(@"%f",1.0 *  self.currentSize/self.totalSize);self.progressView.progress = 1.0 *  self.currentSize/self.totalSize;//NSLog(@"%@",self.fullPath);
}-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{//1.关闭文件句柄
    [self.handle closeFile];self.handle = nil;NSLog(@"connectionDidFinishLoading");NSLog(@"%@",self.fullPath);
}
@end

(1)第一种方式(NSData)

```objc

//使用NSDta直接加载网络上的url资源(不考虑线程)

-(void)dataDownload

{

//1.确定资源路径

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];

//2.根据URL加载对应的资源

NSData *data = [NSData dataWithContentsOfURL:url];

//3.转换并显示数据

UIImage *image = [UIImage imageWithData:data];

self.imageView.image = image;

}

```

(2)第二种方式(NSURLConnection-sendAsync)

```objc

//使用NSURLConnection发送异步请求下载文件资源

-(void)connectDownload

{

//1.确定请求路径

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"];

//2.创建请求对象

NSURLRequest *request = [NSURLRequest requestWithURL:url];

//3.使用NSURLConnection发送一个异步请求

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

//4.拿到并处理数据

UIImage *image = [UIImage imageWithData:data];

self.imageView.image = image;

}];

}

```

(3)第三种方式(NSURLConnection-delegate)

```objc

//使用NSURLConnection设置代理发送异步请求的方式下载文件

-(void)connectionDelegateDownload

{

//1.确定请求路径

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

//2.创建请求对象

NSURLRequest *request = [NSURLRequest requestWithURL:url];

//3.使用NSURLConnection设置代理并发送异步请求

[NSURLConnection connectionWithRequest:request delegate:self];

}

#pragma mark--NSURLConnectionDataDelegate

//当接收到服务器响应的时候调用,该方法只会调用一次

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

//创建一个容器,用来接收服务器返回的数据

self.fileData = [NSMutableData data];

//获得当前要下载文件的总大小(通过响应头得到)

NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

self.totalLength = res.expectedContentLength;

NSLog(@"%zd",self.totalLength);

//拿到服务器端推荐的文件名称

self.fileName = res.suggestedFilename;

}

//当接收到服务器返回的数据时会调用

//该方法可能会被调用多次

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

//    NSLog(@"%s",__func__);

//拼接每次下载的数据

[self.fileData appendData:data];

//计算当前下载进度并刷新UI显示

self.currentLength = self.fileData.length;

NSLog(@"%f",1.0* self.currentLength/self.totalLength);

self.progressView.progress = 1.0* self.currentLength/self.totalLength;

}

//当网络请求结束之后调用

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

{

//文件下载完毕把接受到的文件数据写入到沙盒中保存

//1.确定要保存文件的全路径

//caches文件夹路径

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

NSString *fullPath = [caches stringByAppendingPathComponent:self.fileName];

//2.写数据到文件中

[self.fileData writeToFile:fullPath atomically:YES];

NSLog(@"%@",fullPath);

}

//当请求失败的时候调用该方法

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

NSLog(@"%s",__func__);

}

```

#####5.0  大文件的下载

(1)实现思路

边接收数据边写文件以解决内存越来越大的问题

(2)核心代码

```objc

//当接收到服务器响应的时候调用,该方法只会调用一次

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

//0.获得当前要下载文件的总大小(通过响应头得到)

NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;

self.totalLength = res.expectedContentLength;

NSLog(@"%zd",self.totalLength);

//创建一个新的文件,用来当接收到服务器返回数据的时候往该文件中写入数据

//1.获取文件管理者

NSFileManager *manager = [NSFileManager defaultManager];

//2.拼接文件的全路径

//caches文件夹路径

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

NSString *fullPath = [caches stringByAppendingPathComponent:res.suggestedFilename];

self.fullPath  = fullPath;

//3.创建一个空的文件

[manager createFileAtPath:fullPath contents:nil attributes:nil];

}

//当接收到服务器返回的数据时会调用

//该方法可能会被调用多次

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

//1.创建一个用来向文件中写数据的文件句柄

//注意当下载完成之后,该文件句柄需要关闭,调用closeFile方法

NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];

//2.设置写数据的位置(追加)

[handle seekToEndOfFile];

//3.写数据

[handle writeData:data];

//4.计算当前文件的下载进度

self.currentLength += data.length;

NSLog(@"%f",1.0* self.currentLength/self.totalLength);

self.progressView.progress = 1.0* self.currentLength/self.totalLength;

}

```

转载于:https://www.cnblogs.com/cqb-learner/p/5861432.html

ios开发网络学习三:NSURLConnection小文件大文件下载相关推荐

  1. ios开发网络学习九:NSURLSessionDownloadTask实现大文件下载

    一:NSURLSessionDownloadTask:实现文件下载:无法监听进度 #import "ViewController.h"@interface ViewControll ...

  2. ios开发网络学习:一:NSURLConnection发送GET,POST请求

    #import "ViewController.h"@interface ViewController ()<NSURLConnectionDataDelegate> ...

  3. 02.iOS开发网络篇—HTTP协议

    iOS开发网络篇-HTTP协议 说明:apache tomcat服务器必须占用8080端口 一.URL 1.基本介绍 URL的全称是Uniform Resource Locator(统一资源定位符) ...

  4. iOS开发网络篇—多线程断点下载

    iOS开发网络篇-多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  5. iOS开发网络篇—使用ASI框架进行文件下载

    iOS开发网络篇-使用ASI框架进行文件下载 说明:本文介绍iOS网络编程中经常用到的框架ASI,如何使用该框架进行文件的下载. 一.简单介绍 代码示例: 1 #import "YYView ...

  6. iOS开发网络篇—数据缓存

    iOS开发网络篇-数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造成以 ...

  7. iOS开发中一些有用的小代码

    1.判断邮箱格式是否正确的代码: //利用正则表达式验证 -(BOOL)isValidateEmail:(NSString *)email { NSString *emailRegex = @&quo ...

  8. iOS开发网络篇—搭建本地服务器

    iOS开发网络篇-搭建本地服务器 一.简单说明 说明:提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提示:提前准备好的软件 apache- ...

  9. iOS开发——网络请求案例汇总(AFNetworking)

    我在之前一篇博客中实现了使用NSURLConnection或者NSURLSession来请求网络数据,用的都是苹果自带的方法.请参考<iOS开发--网络请求案例汇总>.现在我们使用最流行的 ...

  10. Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 ---- 小达

    Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 拿好素材之后,打开你们的开发工具,小达这里用的是android studio1.0, 新建一个项目,打开activity_main ...

最新文章

  1. C++编程基础二 04-默认实参
  2. 清华计算机知识工程怎么样,张民(muslv)清华大学计算机系知识工程组 硕士清华大学.ppt...
  3. 手写简版spring --9--对象作用域和FactoryBean
  4. python全栈开发-json和pickle模块(数据的序列化)
  5. 深入理解kestrel的应用
  6. 例子:好友列表选中效果
  7. redis专题:redis的常用数据结构及使用场景
  8. 使用zabbix监控mariadb性能状态
  9. [Java] 蓝桥杯ADV-96 算法提高 复数求和
  10. Numpy安装+导入出错的解决方法
  11. .net在web.config中设置网站编码格式
  12. Java开发笔记(一百三十一)Swing的列表框
  13. Eclipse安装反编译工具Eclipse Class Decompiler:实现不下载源码,查看源文件
  14. 天梯赛-愿天下有情人都是失散多年的兄妹-题解
  15. 【语音智能管家】之语音唤醒(附演示视频)
  16. imprinted weights
  17. vela和鸿蒙,小米Vela系统发布,将对标华为鸿蒙OS
  18. Velocity最简易的Servlet加载
  19. 解压tar.zx命令
  20. jupyter notebook OSError: [WinError 10106] 无法加载或初始化请求的服务提供程序, 错误提示解决方法

热门文章

  1. Metamask + remix:在ropsten测试链上取出已经部署的合约并进行一些操作
  2. 基于SSM的疫情数据统计分析系统
  3. jsp el表达式无法正常显示解决方法
  4. java队列 notify_java使用线程做一个消息队列,wait,notify
  5. 天平应什么放置_电子天平,你不得不知道的那些事!
  6. vue基础之v-for,key
  7. es6之模块化(module)--绝对能看懂
  8. javascript 变量及作用域(栈、堆、块级作用域、执行环境)详细篇
  9. 开局崩盘!IDEA 2020 无法启动的解决办法|赠送 IDEA 2020 新功能
  10. 适配器模式之享元模式