ios开发网络学习五:输出流以及文件上传
一:输出流
#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) NSString *fullPath;
/** 连接对象 */
@property (nonatomic, strong) NSURLConnection *connect;
/** 输出流*/
@property (nonatomic, strong) NSOutputStream *stream;
@end @implementation ViewController - (IBAction)startBtnClick:(id)sender {
[self download];
}
- (IBAction)cancelBtnClick:(id)sender {
[self.connect cancel];
}
- (IBAction)goOnBtnClick:(id)sender {
[self download];
} //内存飙升
-(void)download
{
//1.url
// NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"]; NSURL *url = [NSURL URLWithString:@"http://www.33lc.com/article/UploadPic/2012-10/2012102514201759594.jpg"]; //2.创建请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //设置请求头信息,告诉服务器值请求一部分数据range
/*
bytes=0-100
bytes=-100
bytes=0- 请求100之后的所有数据
*/
NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:range forHTTPHeaderField:@"Range"];
NSLog(@"+++++++%@",range); //3.发送请求
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self];
self.connect = connect;
} #pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"didReceiveResponse"); //1.得到文件的总大小(本次请求的文件数据的总大小 != 文件的总大小)
// self.totalSize = response.expectedContentLength + self.currentSize; if (self.currentSize >) {
return;
} self.totalSize = response.expectedContentLength; //2.写数据到沙盒中
self.fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.jpg"]; NSLog(@"%@",self.fullPath);
//3.创建输出流
// NSOutputStream
// NSInputStream
/*
第一个参数:文件的路径
第二个参数:YES 追加
特点:如果该输出流指向的地址没有文件,那么会自动创建一个空的文件
*/
NSOutputStream *stream = [[NSOutputStream alloc]initToFileAtPath:self.fullPath append:YES]; //打开输出流
[stream open];
self.stream = stream;
} -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//写数据
[self.stream write:data.bytes maxLength:data.length]; //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
{ //关闭流
[self.stream close];
self.stream = nil; NSLog(@"connectionDidFinishLoading");
NSLog(@"%@",self.fullPath);
}
@end
#####7.0 输出流
(1)使用输出流也可以实现和NSFileHandle相同的功能
(2)如何使用
```objc
//1.创建一个数据输出流
/*
第一个参数:二进制的流数据要写入到哪里
第二个参数:采用什么样的方式写入流数据,如果YES则表示追加,如果是NO则表示覆盖
*/
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:fullPath append:YES];
//只要调用了该方法就会往文件中写数据
//如果文件不存在,那么会自动的创建一个
[stream open];
self.stream = stream;
//2.当接收到数据的时候写数据
//使用输出流写数据
/*
第一个参数:要写入的二进制数据
第二个参数:要写入的数据的大小
*/
[self.stream write:data.bytes maxLength:data.length];
//3.当文件下载完毕的时候关闭输出流
//关闭输出流
[self.stream close];
self.stream = nil;
```
二:文件上传
//文件上传步骤 /**
* 1:NSURLConnection的post请求:1:需要初始化url确定请求路径,设置可变请求对象NSMutableURLRequest,设置请求方式post,设置请求头,设置请求体,发送异步请求文件上传
*/ /*
1.设置请求头 :boundary为分隔符
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryjv0UfA04ED44AhWx
2.按照固定的格式拼接请求体的数据 ------WebKitFormBoundaryjv0UfA04ED44AhWx
Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png"
Content-Type: image/png ------WebKitFormBoundaryjv0UfA04ED44AhWx
Content-Disposition: form-data; name="username" 123456
------WebKitFormBoundaryjv0UfA04ED44AhWx-- */
//拼接请求体的数据格式
/*
拼接请求体
分隔符:----WebKitFormBoundaryjv0UfA04ED44AhWx
1)文件参数
--分隔符
Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png"
Content-Type: image/png(MIMEType:大类型/小类型)
空行
文件参数
2)非文件参数
--分隔符
Content-Disposition: form-data; name="username"
空行
123456
3)结尾标识
--分隔符--
*/
#import "ViewController.h" #define Kboundary @"----WebKitFormBoundaryjv0UfA04ED44AhWx"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding] @interface ViewController () @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self upload];
} -(void)upload
{
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"]; //2.创建可变的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //3.设置请求方法
request.HTTPMethod = @"POST"; //4.设置请求头信息
//Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryjv0UfA04ED44AhWx
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"]; //5.拼接请求体数据
NSMutableData *fileData = [NSMutableData data];
//5.1 文件参数
/*
--分隔符
Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png"
Content-Type: image/png(MIMEType:大类型/小类型)
空行
文件参数
*/
//字符串转码:dataUsingEncoding
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; //name:file 服务器规定的参数
//filename:Snip20160225_341.png 文件保存到服务器上面的名称
//Content-Type:文件的类型
//其中的\代表转义,对双引号进行转义
[fileData appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20160225_341.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine]; UIImage *image = [UIImage imageNamed:@"Snip20160225_341"]; /**
* 1:将image转化成data的格式:UIImagePNGRepresentation或是jpeg
*
*/
//UIImage --->NSData
NSData *imageData = UIImagePNGRepresentation(image);
[fileData appendData:imageData];
[fileData appendData:KNewLine]; //5.2 非文件参数
/*
--分隔符
Content-Disposition: form-data; name="username"
空行
123456
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine];
[fileData appendData:KNewLine];
[fileData appendData:[@"" dataUsingEncoding:NSUTF8StringEncoding]];
[fileData appendData:KNewLine]; //5.3 结尾标识
/*
--分隔符--
*/
[fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; //6.设置请求体
request.HTTPBody = fileData; //7.发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //8.解析数据
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
} @end
#####10.0 文件的上传
- 10.1 文件上传步骤
(1)确定请求路径
(2)根据URL创建一个可变的请求对象
(3)设置请求对象,修改请求方式为POST
(4)设置请求头,告诉服务器我们将要上传文件(Content-Type)
(5)设置请求体(在请求体中按照既定的格式拼接要上传的文件参数和非文件参数等数据)
001 拼接文件参数
002 拼接非文件参数
003 添加结尾标记
(6)使用NSURLConnection sendAsync发送异步请求上传文件
(7)解析服务器返回的数据
- 10.2 文件上传设置请求体的数据格式
//请求体拼接格式
//分隔符:----WebKitFormBoundaryhBDKBUWBHnAgvz9c
//01.文件参数拼接格式
--分隔符
Content-Disposition:参数
Content-Type:参数
空行
文件参数
//02.非文件拼接参数
--分隔符
Content-Disposition:参数
空行
非文件的二进制数据
//03.结尾标识
--分隔符--
- 10.3 文件上传相关代码
```objc
- (void)upload
{
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
//2.创建一个可变的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3.设置请求方式为POST
request.HTTPMethod = @"POST";
//4.设置请求头
NSString *filed = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:filed forHTTPHeaderField:@"Content-Type"];
//5.设置请求体
NSMutableData *data = [NSMutableData data];
//5.1 文件参数
/*
--分隔符
Content-Disposition:参数
Content-Type:参数
空行
文件参数
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"test.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:KnewLine];
[data appendData:KnewLine];
UIImage *image = [UIImage imageNamed:@"test"];
NSData *imageData = UIImagePNGRepresentation(image);
[data appendData:imageData];
[data appendData:KnewLine];
//5.2 非文件参数
/*
--分隔符
Content-Disposition:参数
空行
非文件参数的二进制数据
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
[data appendData:KnewLine];
[data appendData:KnewLine];
NSData *nameData = [@"wendingding" dataUsingEncoding:NSUTF8StringEncoding];
[data appendData:nameData];
[data appendData:KnewLine];
//5.3 结尾标识
//--分隔符--
[data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KnewLine];
request.HTTPBody = data;
//6.发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
//7.解析服务器返回的数据
NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}];
}
```
ios开发网络学习五:输出流以及文件上传的更多相关文章
- ios开发网络学习五:MiMEType ,多线程下载文件思路,文件的压缩和解压缩
一:MiMEType:一般可以再百度上搜索到相应文件的MiMEType,或是利用c语言的api去获取文件的MiMEType : //对该文件发送一个异步请求,拿到文件的MIMEType - (void ...
- ios网络学习------10 原生API文件上传
使用原生态的api上传文件的实现: #import "MainViewController.h" @interface MainViewController () @propert ...
- iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充
一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...
- ios网络学习------11 原生API文件上传之断点续传思路
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmcyMDA5MzAzNTEz/font/5a6L5L2T/fontsize/400/fill/I0 ...
- iOS开发之网络编程--使用NSURLConnection实现文件上传
前言:使用NSURLConnection实现文件上传有点繁琐. 本文并没有介绍使用第三方框架上传文件. 正文: 这里先提供用于编码测试的接口:http://120.25.226.186:3281 ...
- 【Java Web开发学习】Spring MVC文件上传
[Java Web开发学习]Spring MVC文件上传 转载:https://www.cnblogs.com/yangchongxing/p/9290489.html 文件上传有两种实现方式,都比较 ...
- ios开发网络学习十二:NSURLSession实现文件上传
#import "ViewController.h" // ----WebKitFormBoundaryvMI3CAV0sGUtL8tr #define Kboundary @&q ...
- IOS网络第五天 AFN-02-文件上传,底部弹出窗体,拍照和相册获取图片上传
************** #import "HMViewController.h" #import "AFNetworking.h" @interface ...
- [原创]java WEB学习笔记49:文件上传基础,基于表单的文件上传,使用fileuoload 组件
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- CSDN-markdown语法之怎样插入图片
文件夹 图片上传方式 插入在线图片 插入本地图片 图片链接方式 行内式图片链接 參考式图片链接 几个问题探讨 问题1:图片上传和图片链接两种方式的差别 问题2:Markdown中怎样指定图片的高和宽? ...
- Impala是什么?
Impala是Cloudera公司主导开发的新型查询系统,它提供SQL语义,能查询存储在Hadoop的HDFS和HBase中的PB级大数据.已有的Hive系统虽然也提供了SQL语义,但由于Hive底层 ...
- carousel轮播器
<div id="myCarousel" class="carousel slide" data-ride="carousel" st ...
- js全选反选按钮实现
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 用两个栈实现队列与用两个队列实现栈(Python实现)
用两个栈实现队列: class QueueWithTwoStacks(object): def __init__(self): self._stack1 = [] self._stack2 = [] ...
- Android开发工具之adt-bundle-windows
adt-bundle-windows是非常久之前的android开发工具.是集成了ADT版本号的eclipse,可是里面并没有下载SDK.这个须要自己单独下载,这个工具适合刚開始学习的人使用. 由于刚 ...
- 1.html+css页面设计
转自:http://www.cnblogs.com/ywang/archive/2014/04/16/3668638.html 今天用html+css做一个最简单的页面.效果图如下: 说明:这里的韩文 ...
- FTP、WEB虚拟目录作用
随风原文FTP.WEB虚拟目录作用 在 IIS中,双击您要为之添加虚拟目录的服务以显示其属性表. 单击“目录”选项卡. 单击“添加”. 单击“浏览”从“目录”框中选择一个目录. ...
- bootstrap课程5 bootstrap中的组件使用的注意事项是什么
bootstrap课程5 bootstrap中的组件使用的注意事项是什么 一.总结 一句话总结: 1.img-responsive的作用是什么(其实还是要多看手册)? 看起来像width=100%的效 ...
- 多类 SVM 的损失函数及其梯度计算
CS231n Convolutional Neural Networks for Visual Recognition -- optimization 1. 多类 SVM 的损失函数(Multicla ...