大文件与小文件下载

小文件

如果文件比较小,下载方式会比较多

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(@"----写入完毕---");
    
}
View Code

如果是下载图片,还可以利用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;
    
}
View Code

 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];
}
View Code

 二.(主要使用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) {
        
    }];
}

大文件与小文件下载的本质区别

小文件是全部下载之后进行拼接,内存占用会不断增大

大文件是下载一点就去文件写一点,内存占用基本不变

原文地址:https://www.cnblogs.com/langji/p/5362423.html