zoukankan      html  css  js  c++  java
  • 大文件与小文件下载

    小文件

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

    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) {
            
        }];
    }

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

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

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

  • 相关阅读:
    session与cookie的浅谈
    jmeter的正则表达式编辑器
    安装canvas
    sql server连接oracle并实现增删改查
    在iOS下-input[disabled] 颜色变浅兼容&& input[readonly]仍可获取焦点解决方法
    快速向表中插入大量数据Oracle中append与Nologging
    JavaScript 删除某个数组中指定的对象和删除对象属性
    ORA-00911: invalid character 错误解决
    SQL Server Varchar 中文乱码问题与使用SQL Server Management Studio管理软件查询出来的字段限制
    SqlServer该如何合适的索引
  • 原文地址:https://www.cnblogs.com/langji/p/5362423.html
Copyright © 2011-2022 走看看