一:小文件下载

#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.url
NSURL *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;

}

```

ios开发网络学习三:NSURLConnection小文件大文件下载的更多相关文章

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

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

  2. ios开发网络学习四:NSURLConnection大文件断点下载

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

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

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

  4. ios开发网络学习十二:NSURLSession实现文件上传

    #import "ViewController.h" // ----WebKitFormBoundaryvMI3CAV0sGUtL8tr #define Kboundary @&q ...

  5. ios开发网络学习五:MiMEType ,多线程下载文件思路,文件的压缩和解压缩

    一:MiMEType:一般可以再百度上搜索到相应文件的MiMEType,或是利用c语言的api去获取文件的MiMEType : //对该文件发送一个异步请求,拿到文件的MIMEType - (void ...

  6. ios开发网络学习五:输出流以及文件上传

    一:输出流 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelega ...

  7. ios开发网络学习AFN三:AFN的序列化

    #import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...

  8. iOS开发——网络篇——HTTP/NSURLConnection(请求、响应)、http响应状态码大全

    一.网络基础 1.基本概念> 为什么要学习网络编程在移动互联网时代,移动应用的特征有几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图只有通过网络跟外界进行数据交互.数据更新, ...

  9. ios开发网络学习AFN框架的使用一:get和post请求

    #import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...

随机推荐

  1. WordPress出现Briefly unavailable for scheduled maintenance. Check back in a minute. 的解决方法

    WordPress出现 Briefly unavailable for scheduled maintenance. Check back in a minute. 解决方法: 登入FTP,然后把Wo ...

  2. Aruba 云服务代金券

    Aruba 云服务代金券 Aruba Cloud是欧洲的一家VPS供应商,他家的VPS是基于VMware的,有英国.法国.德国.意大利.捷克5处数据中心,每个月最低1欧元,非欧洲企业客户可以免税 这里 ...

  3. js---BOM 的理解方法

    windows 方法 window.close(); //关闭窗口   window.alert("message"); //弹出一个具有OK按钮的系统消息框,显示指定的文本   ...

  4. Vue的学习--遇到的一些问题和解决方法

    包括: 1.Missing space before function parentheses 2.如何给.vue文件的页面添加css 3.如何给.vue文件页面里的元素添加监听器 4.如何为每一个页 ...

  5. BZOJ1030: [JSOI2007]文本生成器(Trie图+dp)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  6. 腾讯2016实习生面试经验(已经拿到offer)

      忐忑了好几天,今天最终收到深圳总部的电话.允许录用我为2016年实习生,感觉整个天空都放晴了.坐标:武汉大学,给大家说说我的面试经历吧,我投的是软件开发--应用开发方向. 一.校招流程 投递简历- ...

  7. 5.3.7 UserDict对象

    用户自己定义字典类UserDict,它是封装了一个字典类dict.主要使用来拷贝一个字典的数据.而不是共享同一份数据. class collections.UserDict([initialdata] ...

  8. imageView-scaleType 图片压缩属性

    今天用到了图片压缩的属性,自己参照网上的说明,验证了一下,截图如下 (1)当图片背景是方形的时候 代码如下 <LinearLayout android:id="@+id/l31&quo ...

  9. 【Educational Codeforces Round 33 A】Chess For Three

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟题.知道哪个人是旁观者就好 [代码] /* 1.Shoud it use long long ? 2.Have you ever ...

  10. JS预解释的总结

    预解释阶段发生在创建了堆内存,让代码执行之前,对当前作用域中带var和function的进行预解释 在浏览器解析执行代码的时候,会提前把带var和function的代码声明或定义,提前放在作用域的最前 ...