iOS实现文件下载功能

本文实例为大家分享了iOS实现文件下载的具体代码,供大家参考,具体内容如下

说明:

1).获取网络文件大小;

2).开启循环,计算每段position开始与结束位置,通过Range头字段按块获取文件数据流;

3).使用NSFileHandle追加方式将NSData文件数据写入本地文件。

1、用HEAD请求方式获取网络文件大小:

/*
 获取网络文件大小
 */
- (long long)getNetFileLen:(NSURL *)url{
    //1.创建request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10];
    //设置请求方式为HEAD, 只获取头信息
    request.HTTPMethod = @"HEAD";
    
    //2.定义用于接收网络数据的对象
    NSURLResponse *response = nil;
    
    //3.同步请求网络,将结果存入response
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
    
    //返回文件大小
    return response.expectedContentLength;
}

2、开启异步线程,请求网络下载文件:

/*
 下载文件
 */
- (void)downloadFile:(NSString *)urlStr done:(void (^)())done{
    
    //1.获取系统自带全局队列
    //并行队列,多个线程并发执行:DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.异步执行
    dispatch_async(queue, ^{
        //创建url对象
        NSURL *url = [[NSURL alloc] initWithString:urlStr];
        NSLog(@"url: %@", urlStr);
        
        //获取本地已下载文件大小
        long long localFileLen = [self getLocalFileLen];
        NSLog(@"localFileLen : %lld", localFileLen);
        
        //获取网络文件大小
        long long netFileLen = [self getNetFileLen:url];
        NSLog(@"netFileLen : %lld", netFileLen);
        
        if(localFileLen == netFileLen){//一样表示存在了
            return;
        }
        
        //每次从服务端获取的文件数据大小
        long long itemSize = 1024 * 20;
        
        //一段数据的开始position位置
        long long startPos = 0;
        
        //一段数据的结尾position位置
        long long endPos = 0;
        
        while (startPos < netFileLen) {
            //计算结尾position
            endPos = startPos + itemSize - 1;
            
            //组装range字段,用于请求头
            NSString *range = [NSString stringWithFormat:@"Bytes=%lld-%lld", startPos, endPos];
            
            NSLog(@"range : %@", range);
            
            //重新计算下一段数据开始position
            startPos = startPos + itemSize;
            
            /*
             缓存策略
             NSURLRequestUseProtocolCachePolicy = 0, 默认,内存缓存
             NSURLRequestReloadIgnoringLocalCacheData = 1, 忽略本地内存缓存
             NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
             NSURLRequestReturnCacheDataElseLoad = 2,
             NSURLRequestReturnCacheDataDontLoad = 3,
             */
            
            //(1)创建request
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
            
            //设置Range请求头
            [request setValue:range forHTTPHeaderField:@"Range"];
            
            //(2)定义用于接收网络信息的对象
            NSURLResponse *response = nil;
            
            //(3)同步请求网络
            NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
            
            //(4)将数据写入文件
            [self appendFile:data];
        }
        
        //3.切回主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            //调用完成方法
            done();
        });
        
    });
}

3、获取本地文件大小:

/*
 获取本地文件大小
 */
- (long long)getLocalFileLen{
    //目录路径
    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    //文件路径
    NSString *filePath = [cacheDir stringByAppendingPathComponent:@"qq.dmg"];
    //获取本地文件NSDictionary信息
    NSDictionary *map = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL];
    //获取本地文件大小,转为longlong类型
    return [map[NSFileSize] longLongValue];
}

4、将NSData数据追加写入文件:

/*
 将NSData数据追加写入文件
 */
- (void)appendFile:(NSData *)data{
    //目录路径
    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    //文件路径
    NSString *filePath = [cacheDir stringByAppendingPathComponent:@"qq.dmg"];
    
    NSLog(@"filePath : %@", filePath);
    
    //创建文件操作类,NSFileHandle支持追加写入方式
    NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:filePath];
    
    if(!file){//文件不存在时,直接覆盖方式写入
        [data writeToFile:filePath atomically:YES];
        return;
    }
    //跳到文件末尾
    [file seekToEndOfFile];
    
    //写数据
    [file writeData:data];
    
    //关闭文件流
    [file closeFile];
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS NSURLSessionDownloadTask设置代理文件下载的示例

    通过设置代理我们可以拿到下载进度,对于大文件,我们还需要做到开始.暂停.继续以及取消等相应操作,这篇文章先简单的介绍一下通过代理来实现文件下载的问题: #import "ViewController.h" @interface ViewController ()<NSURLSessionDownloadDelegate> @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *&g

  • iOS开发-实现大文件下载与断点下载思路

    大文件下载 方案一:利用NSURLConnection和它的代理方法,及NSFileHandle(iOS9后不建议使用) 相关变量: @property (nonatomic,strong) NSFileHandle *writeHandle; @property (nonatomic,assign) long long totalLength; 1>发送请求 // 创建一个请求 NSURL *url = [NSURL URLWithString:@""]; NSURLReque

  • iOS工程中怎么判断下载的流是PDF文件

    又是一个因为太简单在网上却搜不到答案的问题. 先拿一个PDF文件转换成NSData类型.通过打印得知,前5个字节为<25504446 2d>,用以表明这个文件的类型是PDF. <25504446 2d>转成NSString类型就是@"%PDF-". 因此只要比较前5个字节就能确定请求回来的数据类型. 因此判断方式就是: 说明:data就是网络下载下来的数据. // //pdf二进制文件都是以字符串@"%PDF-"开头的 // NSString

  • iOS利用AFNetworking3.0——实现文件断点下载

    0.导入框架准备工作 1. 将AFNetworking3.0+框架程序拖拽进项目 2. 或使用Cocopod 导入AFNetworking3.0+ 3.  引入 #import "AFNetworking.h" 1.UI准备工作 A. 定义一个全局的 NSURLSessionDownloadTask:下载管理句柄 由其负责所有的网络操作请求 @interface ViewController () { // 下载句柄 NSURLSessionDownloadTask *_downloa

  • iOS NSURLSessionDownloadTask实现文件断点下载的方法

    所谓断点下载:就是实现开始.暂停.继续以及取消等操作.上一篇我们已经谈到了通过设置代理实现文件的连续下载,也就是文件从开始一直到下载完成,中途不中断.这种方式比较适用一些小文件的下载,比如:微信里面的表情包下砸.就算中途因为其他原因中断了下载,我们重新开始下载也不会浪费用户很多流量,用户体验也不会因此变的很差. 在实现断点下载之前:我们需要清楚对什么进行断点下载,是对网络请求NSURLSession还是对任务NSURLSessionDownloadTask.下载文件只会发送一次请求,我们操作应该

  • iOS开发中文件的上传和下载功能的基本实现

    文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代码. 主控制器的关键代码: 复制代码 代码如下: YYViewController.m #import "YYViewController.h" #define YYEncode(str) [str dataUsingEncoding:NSUTF8StringEncoding] @interface YYV

  • iOS开发网络篇—实现大文件的多线程断点下载

    说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要类如下: 完成的实现代码如下: 主控制器中的代码: #import "YYViewController.h" #import

  • iOS实现文件下载功能

    本文实例为大家分享了iOS实现文件下载的具体代码,供大家参考,具体内容如下 说明: 1).获取网络文件大小: 2).开启循环,计算每段position开始与结束位置,通过Range头字段按块获取文件数据流: 3).使用NSFileHandle追加方式将NSData文件数据写入本地文件. 1.用HEAD请求方式获取网络文件大小: /*  获取网络文件大小  */ - (long long)getNetFileLen:(NSURL *)url{     //1.创建request     NSMut

  • jsp文件下载功能实现代码

    本文实例为大家分享了jsp实现文件下载功能的3种方法,供大家参考,具体内容如下 第一种.采用转发的方式: package cn.jbit.download.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.serv

  • 利用 FormData 对象和 Spring MVC 配合实现Ajax文件下载功能

    Ajax文件下载 利用 FormData 对象和 Spring MVC 配合可以实现Ajax文件上载功能: 步骤 1.导入组件并准备静态脚本 <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency> &l

  • JSP文件下载功能的4种方法

    对于网站来说,网站本身常常需要提供一些资源或者资料进行下载,说到下载莫过于最原始的方法就是在网页上提供下载的网址.今天讲述的还有另外的几种实现文件下载的方法,对于哪种方法更好这也是看自己的需求. 1.最直接最简单的,方式是把文件地址直接放到html页面的一个链接中.这样做的缺点是把文件在服务器上的路径暴露了,并且还无法对文件下载进行其它的控制(如权限).这个就不写示例了.  2.在服务器端把文件转换成输出流,写入到response,以response把文件带到浏览器,由浏览器来提示用户是否愿意保

  • Java Web项目中实现文件下载功能的实例教程

    需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法: 一:通过超链接实现下载 在HTML网页中,通过超链接链接到要下载的文件的地址 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>通过链接下载文件&

  • php实现支持中文的文件下载功能示例

    前言 本文主要给大家介绍了关于php实现支持中文的文件下载功能的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 问题说明 文件下载,通常有一种最为简单的方法,那就是将url直接指向服务器上文件的所在位置.但是这个方法存在很大的安全隐患. 暴露了服务器文件目录结构 无法禁止非法请求来源,无法对文件下载请求做安全验证 解决方案 一.将文件下载请求映射到后端程序url 借助http服务器(apache/nginx)实现映射功能 这里以apache为例进行说明 借助apach

  • C#实现文件上传及文件下载功能实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: public ActionResult Upload() { // var pathUrl = "http://" + Request.Url.Authority; var file = Request.Files["Filedata"]; var uploadFileName = file.FileName; string filePath = "/File/" + uploadFileNa

  • PHP实现的文件操作类及文件下载功能示例

    本文实例讲述了PHP实现的文件操作类及文件下载功能.分享给大家供大家参考,具体如下: 文件操作类: <?php // Copyright 2005, Lee Babin (lee@thecodeshoppe.com) // This code may be used and redistributed without charge // under the terms of the GNU General Public // License version 2.0 or later -- www

  • Ruby使用eventmachine为HTTP服务器添加文件下载功能

    思路: 使用ruby eventmachine和em-http-server gem,完成一个简单的提供文件下载功能的HttpServer: 使用了EM的FileStreamer来异步发送文件,发送文件时先组装了header,然后调用FileStreamer. 代码: require 'rubygems' require 'eventmachine' require 'em-http-server' class HTTPHandler < EM::HttpServer::Server attr_

  • Struts2实现文件下载功能代码分享(文件名中文转码)

    struts2文件下载功能实现代码如下所示: Action文件 public class DownLoadAction extends ActionSupport { /** * */ private static final long serialVersionUID = 5879762231742395104L; private String fileName;//用户请求的文件名 private String inputPath;//下载资源的路径(在struts配置文件中设置) publ

随机推荐