一、小文件下载

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

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

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

        UIImage *image = [UIImage imageWithData:data];

    }];

二、大文件下载

1、利用NSMutableData,缺点是会导致内存暴涨(以下用fileData,也就是注释部分)
2、利用NSFileHandle,该类就是专门用于操作文件(handle)

@interface ViewController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *progressView; @property (nonatomic, assign)NSUInteger currentLength; /**< 当前已经接收的长度 */
@property (nonatomic, assign)NSUInteger totalLength; /**< 需要接收的总长度 */ @property (nonatomic, strong)NSMutableData *fileData; /**< 用于存储下载的文件 */ @property (nonatomic, strong) NSFileHandle *handle; /**< 文件句柄 */ @property (nonatomic, copy) NSString *path; /**< 保存文件的路径 */
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
} #pragma mark - NSURLConnectionDataDelegate
// 接收到服务器的响应
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 根据文件名称, 拼接保存文件的路径
self.path = [response.suggestedFilename cacheDir]; // 保存文件的总大小
self.totalLength = response.expectedContentLength; // 创建一个空的文件, 用于存储下载的数据
NSFileManager *manager = [NSFileManager defaultManager];
if([manager createFileAtPath:self.path contents:nil attributes:nil]){
NSLog(@"创建空文件成功");
}
}
// 接收到服务器的数据调用(会调用一次或多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 将每次下载的内容存储到fileData中
// 会导致内存暴涨
// [self.fileData appendData:data]; // 告诉handle从什么地方开始写入
// 从没有数据的地方开始写入, 也就是在上一次的后面拼接
[self.handle seekToEndOfFile];
// 写入数据
[self.handle writeData:data]; // 计算进度
self.currentLength += data.length;
self.progressView.progress = 1.0 * self.currentLength / self.totalLength;
}
// 接收完毕时调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// [self.fileData writeToFile:@"/Users/xiaomage/Desktop/abc.mp4" atomically:YES]; // 关闭文件句柄
[self.handle closeFile];
self.handle = nil;
} // 接收发生错误时调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{ } #pragma mark - lazy
- (NSMutableData *)fileData
{
if (!_fileData) {
_fileData = [NSMutableData data];
}
return _fileData;
} - (NSFileHandle *)handle
{
if (!_handle) {
// NSFileHandle类就是专门用于操作文件
_handle = [NSFileHandle fileHandleForWritingAtPath:self.path];
}
return _handle;
} @end

3、使用NSOutputStream(输出流)

@interface ViewController ()<NSURLConnectionDataDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *progressView; @property (nonatomic, assign)NSUInteger currentLength; /**< 当前已经接收的长度 */
@property (nonatomic, assign)NSUInteger totalLength; /**< 需要接收的总长度 */ @property (nonatomic, copy) NSString *path; /**< 保存文件的路径 */ @property (nonatomic, strong) NSOutputStream *outputStream ; /**< 输出流 */ @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
} #pragma mark - NSURLConnectionDataDelegate
// 接收到服务器的响应
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 根据文件名称, 拼接保存文件的路径
self.path = [response.suggestedFilename cacheDir];
NSLog(@"%@", self.path); // 保存文件的总大小
self.totalLength = response.expectedContentLength;
NSLog(@"%zd", response.expectedContentLength); }
// 接收到服务器的数据调用(会调用一次或多次)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 直接写入数据
/*
第一个参数: 需要写入的数据
第二个参数: 写入数据的大小
*/
[self.outputStream write:data.bytes maxLength:data.length]; // 计算进度
self.currentLength += data.length;
self.progressView.progress = 1.0 * self.currentLength / self.totalLength;
}
// 接收完毕时调用
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 关闭输出流
[self.outputStream close];
self.outputStream = nil;
} // 接收发生错误时调用
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{ } - (NSOutputStream *)outputStream
{
if (!_outputStream) {
/*
第一个参数: 告诉系统数据流需要输出到哪个文件中
第二个参数: 如果传入YES, 代表每次都在上一次的后面追加
如果传入NO, 代表每次都从头开始
*/
_outputStream = [NSOutputStream outputStreamToFileAtPath:self.path append:YES]; // 注意: 如果想利用输出流写入数据, 一定要打开数据流
// 如果数据流打开的文件不存在, 那么会自动创建个新的
[_outputStream open];
}
return _outputStream;
} @end

三、文件压缩/解压缩(使用三方框架ZipArchive)

在ZipArchive框架中有一下几个方法可快速实现文件压缩和解压缩

// 第一个参数: 压缩后的文件保存到什么地方(zip文件)
// 第二个参数: 哪些文件需要压缩(传入一个存了文件名的数组)
+ (BOOL)createZipFileAtPath:(NSString *)path
withFilesAtPaths:(NSArray *)paths; // 第一个参数: 压缩后的文件保存到什么地方(zip文件)
// 第二个参数: 哪个文件夹的文件需要压缩(传入你想压缩的文件名)
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath; // 第一个参数:需要解压的文件
// 第二个参数:解压到什么地方(传入解压缩的目的文件名)
+ (BOOL)unzipFileAtPath:(NSString *)path
toDestination:(NSString *)destination;

四、MIMEType(获取文件类型)

文件的万能类型 application/octet-stream
1、利用NSURLConnection

- (NSString *)MIMEType:(NSURL *)url
{
// 1.创建一个请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2.发送请求(返回响应)
NSURLResponse *response = nil;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
// 3.获得MIMEType
return response.MIMEType;
}

2、C语言API

+ (NSString *)mimeTypeForFileAtPath:(NSString *)path
{
if (![[NSFileManager alloc] init] fileExistsAtPath:path]) {
return nil;
} CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);
CFRelease(UTI);
if (!MIMEType) {
return @"application/octet-stream";
}
return NSMakeCollectable(MIMEType);
}

五、文件的上传

1、如何设置请求头
[request setValue:@"multipart/form-data; boundary=分割线" forHTTPHeaderField:@"Content-Type"];

2、如何设置请求体
+ 文件参数
--分割线\r\n
Content-Disposition: form-data; name="参数名"; filename="文件名"\r\n
Content-Type: 文件的MIMEType\r\n
\r\n
文件数据
\r\n

+ 非文件参数
--分割线\r\n
Content-Disposition: form-data; name="参数名"\r\n
\r\n
参数值
\r\n

+ 结束标记
参数结束的标记
--分割线--\r\n

- 注意事项
+ `请求体`比`请求头`分割线**前面**`多两个--`
+ `结束标记`比`请求体`**后面**`多两个--`

3、上传步骤:
1.创建URL

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];

2.根据URL创建NSURLRequest

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

  2.1设置请求头

request.HTTPMethod = @"POST";
[request setValue:@"multipart/form-data; boundary=分割线" forHTTPHeaderField:@"Content-Type"];

  2.2设置请求体

NSMutableData *data = [NSMutableData data];

    2.2.1设置文件参数
    2.2.2设置非文件参数
    2.2.3设置结束符号

request.HTTPBody = data;

3.利用NSURLConnetion发送请求

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

    }];

六、断点下载(续传)

NSUrlConnection实现断点续传的关键是自定义http request的头部的range域属性。
 

Range头域
  Range头域可以请求实体的一个或者多个子范围。例如,
  表示头500个字节:bytes=0-499
  表示第二个500字节:bytes=500-999
  表示最后500个字节:bytes=-500
  表示500字节以后的范围:bytes=500-
  第一个和最后一个字节:bytes=0-0,-1
  同时指定几个范围:bytes=500-600,601-999
  但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。

NSURL *url1=[NSURL URLWithString:@"下载地址";
NSMutableURLRequest* request1=[NSMutableURLRequest requestWithURL:url1];
[request1 setValue:@"bytes=20000-" forHTTPHeaderField:@"Range"];
[request1 setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
NSData *returnData1 = [NSURLConnection sendSynchronousRequest:request1 returningResponse:nil error:nil];
[self writeToFile:returnData1 fileName:@"SOMEPATH"]; -(void)writeToFile:(NSData *)data fileName:(NSString *) fileName
{
NSString *filePath=[NSString stringWithFormat:@"%@",fileName];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath] == NO){
NSLog(@"file not exist,create it...");
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
}else {
NSLog(@"file exist!!!");
} FILE *file = fopen([fileName UTF8String], [@"ab+" UTF8String]); if(file != NULL){
fseek(file, , SEEK_END);
}
int readSize = [data length];
fwrite((const void *)[data bytes], readSize, , file);
fclose(file);
}

iOS开发——网络篇——文件下载(NSMutableData、NSFileHandle、NSOutputStream)和上传、压缩和解压(三方框架ZipArchive),请求头和请求体格式,断点续传Range的更多相关文章

  1. iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充

    一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...

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

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

  3. iOS开发网络篇—大文件的多线程断点下载

    http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...

  4. iOS开发网络篇—NSURLConnection基本使用

    iOS开发网络篇—NSURLConnection基本使用 一.NSURLConnection的常用类 (1)NSURL:请求地址 (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据 ...

  5. iOS开发网络篇—发送GET和POST请求(使用NSURLSession)

    iOS开发网络篇—发送GET和POST请求(使用NSURLSession) 说明: 1)该文主要介绍如何使用NSURLSession来发送GET请求和POST请求 2)本文将不再讲解NSURLConn ...

  6. iOS开发网络篇—大文件的多线程断点下载(转)

    http://www.cnblogs.com/wendingding/p/3947550.html   iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了 ...

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

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

  8. iOS开发网络篇—文件的上传

    iOS开发网络篇—文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代 ...

  9. iOS开发网络篇—JSON数据的解析

    iOS开发网络篇—JSON数据的解析 iOS开发网络篇—JSON介绍 一.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式 ...

随机推荐

  1. Python 培训之正则表达式

    re 模块 re.math 从头匹配 re.search 结构: re.math(r'^c',a)   不符合返回None 原字符: . 任意字符 [ ] 或者 [A-Z,a-z,b] \d 数字 \ ...

  2. Android应用内语言切换实现(转)

    使用Java反射机制 IActivityManager与ActivityManagerNative都是非公开类,使用Java反射去调用其中的方法. 第一步.使用Android开放的api更改Confi ...

  3. win7怎么显示隐藏文件夹

    1. 点击“组织”,再选择“文件夹和搜索选项”命令. 2. 接下来在打开的“文件夹选项”对话框中,单击“查看”,切换到“查看”选项卡中. 3. 然后在下面的“高级设置”区域,取消“隐藏受保护的操作系统 ...

  4. Apache和Nginx配置支持苹果ATS方法

    什么是ATS功能? ATS是iOS9和OS X El Capitan的一个新特性.开启该功能后,ATS对使用NSURLConnection, CFURL或NSURLSession 等APIs 进行的网 ...

  5. NGINX 配置404错误页面转向

    什么是404页面 如果碰巧网站出了问题,或者用户试图访问一个并不存在的页面时,此时服务器会返回代码为404的错误信息,此时对应页面就是404页面.404页面的默认内容和具体的服务器有关.如果后台用的是 ...

  6. 修改输入框placeholder文字默认颜色-webkit-input-placeholder

    html5为input添加了原生的占位符属性placeholder,高级浏览器都支持这个属性,例如: <input type="text" placeholder=" ...

  7. Object.prototype.toString.call() 区分对象类型

    判断一个对象的类型: /** * 判断对象是否为数组 * @param {Object} source 待判断的对象 * @return {Boolean} true|false */ Object. ...

  8. tmpfs——Linux的一种虚拟内存文件系统

    虚拟内核文件系统(VirtualKernel File Systems),是指那些是由内核产生但不存在于硬盘上(存在于内存中)的文件系统.例如 1.proc proc文件系统为操作系统本身和应用程序之 ...

  9. TFS2012 安装 配置笔记

    TFS2012安装   具体请看文档..   http://yunpan.cn/cmt4X6S7TjEgq  访问密码 464e     TFS2012配置 环境:VS2012  SQL2008  T ...

  10. R语言学习笔记

    向量化的函数 向量化的函数 ifelse/which/where/any/all/cumsum/cumprod/对于矩阵而言,可以使用rowSums/colSums.对于“穷举所有组合问题" ...