小文件
如果文件比较小,下载方式会比较多
1.直接用NSData的 + (id)dataWithConnentsOfURL:(NSURL *)url;
NSData *data = [NSData dataWithContentsOfURL:url]; NSLog(@"%zd",data.length);
2.利用NSURLConnection发送一个HTTP请求去下载
可以直接发送请求,
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { NSLog(@"%zd",data.length); }];
也可以使用代理方法
NSURLConnection *conn = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:url] delegate:self];
具体的代理方法
#pragma mark -<NSURLConnectionDataDelegate> //接收到服务器的响应 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { self.contentLength = [response.allHeaderFields[@"Content-Length"] integerValue]; self.fileData = [NSMutableData data]; } //接收到服务器数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //拼接 [self.fileData appendData:data]; NSLog(@"已经下载:%.2f%%",(1.0*self.fileData.length/self.contentLength)*100); } //下载完成 -(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"%zd",self.fileData.length); //将文件写入沙盒中 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; //文件路径 NSString *file = [caches stringByAppendingPathComponent:@"minion_01.mp4"]; //写入数据 [self.fileData writeToFile:file atomically:YES]; self.fileData = nil; NSLog(@"----写入完毕---"); }
如果是下载图片,还可以利用SDWebImage框架
大文件
一.(主要利用NSURLConnection的代理方法)
1.属性及宏定义
#define DDZFile [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"minion_01.mp4"] @interface ViewController ()<NSURLConnectionDataDelegate> //进度条 @property (weak, nonatomic) IBOutlet UIProgressView *progressView; /** 记录下载进度 */ @property (nonatomic,assign) NSInteger dataLength; /** 文件的总长度 */ @property (nonatomic,assign) NSInteger contentLength; /** 文件句柄对象 */ @property (nonatomic,strong) NSFileHandle *handle; @end
2.刚开始加载时的方法
- (void)viewDidLoad { [super viewDidLoad]; NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]; NSURLConnection *conn = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:url] delegate:self]; }
3.具体的代理方法的实现
#pragma mark -<NSURLConnectionDataDelegate> /** * 接收到响应的时候,创建一个空的文件 */ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { //获得文件的总长度 self.contentLength = [response.allHeaderFields[@"Content-Length"] integerValue]; //文件路径 NSString *file = DDZFile; //创建一个空的文件 [[NSFileManager defaultManager] createFileAtPath:file contents:nil attributes:nil]; //创建文件句柄 self.handle = [NSFileHandle fileHandleForWritingAtPath:DDZFile]; } /** * 接收到具体数据,马上把数据写入到一开始创建好的文件 */ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //记录进度 self.dataLength += data.length; //使用进度条显示 self.progressView.progress = self.dataLength*1.0/self.contentLength; //指定等会数据的写入位置 - 文件内容的最后面 [self.handle seekToEndOfFile]; //写入数据 [self.handle writeData:data]; } //下载完成 -(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"%zd",self.dataLength); NSLog(@"下载完毕---%@",DDZFile); //关闭handle [self.handle closeFile]; self.handle = nil; //清空进度 self.dataLength = 0; }
4.也可以使用NSOutStream来下载文件
#pragma mark -<NSURLConnection> - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { //服务器那边的文件名 // NSLog(@"%@",response.suggestedFilename); //文件路径 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *file = [caches stringByAppendingString:response.suggestedFilename]; //利用NSOutStream往Path中写入数据(append)为YES的话,每次写入都是追加 self.stream = [[NSOutputStream alloc] initToFileAtPath:file append:YES]; //打开流(如果文件不存在会自动创建) [self.stream open]; NSLog(@"%@",file); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.stream write:[data bytes] maxLength:data.length]; } -(void)connectionDidFinishLoading:(NSURLConnection *)connection { [self.stream close]; }
二.(主要使用NSURLSession方法)
- (void)download { //获得NSURLSession对象 NSURLSession *session = [NSURLSession sharedSession]; //获得下载任务 NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_01.png"] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"文件下载完毕-----%@",location); //文件将来存放的真实路径 NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename]; //剪切location的临时文件到真实路径 NSFileManager *manager = [NSFileManager defaultManager]; [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil]; }]; //启动任务 [task resume]; }
NSURLSession是将文件下载到沙盒中的tmp文件目录下
我们需要将其剪切到Caches目录下,才能长久保存。
三.(主要使用AFNetworking框架)
- (void)upload { AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager]; [mgr POST:@"http://120.25.226.186:32812/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { //在这个block中设置需要上传的文件 NSData *data = [NSData dataWithContentsOfFile:@"/Users/DDZ/Desktop/test.png"]; [formData appendPartWithFileData:data name:@"file" fileName:@"test.png" mimeType:@"image/png"]; } success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"---%@",responseObject); } failure:^(NSURLSessionDataTask *task, NSError *error) { }]; }
大文件与小文件下载的本质区别是
小文件是全部下载之后进行拼接,内存占用会不断增大
大文件是下载一点就去文件写一点,内存占用基本不变