ps:本文转载自网络:http://ryan.easymorse.com/?p=12 感谢作者

工程完整代码下载地址:RequestTestDownload1

可完成:

  • 下载指定链接的zip压缩文件
  • 存放在Documents目录下
  • 支持断点续传
  • 显示下载进度
  • 解压到指定目录

——————————————————————————————————————————————

首先,要想在ios项目中使用ASIHttpRequest,必须添加下列框架和类库:

  • ASIHttpRequest   【库的下载地址】
  • CFNetwork.framework
  • SystemConfiguration.framework
  • MobileCoreServices.framework
  • CoreGraphics.framework
  • libz.dylib【这个可能会有变动,有人在ios5.0上运行不了,在项目中添加{libz.1.2.5.dylib}】

——————————————————————————————————————————————

创建一个ASINetworkQueue全局队列,队列里可以添加请求,虽然今天只会用到一个请求,但我们迟早会用到队列,不妨现在就开始创建:

- (void)viewDidLoad

{

queue = [[ASINetworkQueue alloc] init];

//设置支持较高精度的进度追踪

[queue setShowAccurateProgress:YES];

//启动

//启动后,添加到队列的请求会自动执行

[queue go];

}

——————————————————————————————————————————————

紧接着创建我们的下载请求:

- (IBAction)startDownload

{

//Documents路径

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

//下载路径

downloadPath = [[path stringByAppendingPathComponent:@"book.zip"] retain];

//要支持断点续传,缓存路径是不能少的。

NSString *tempPath = [path stringByAppendingPathComponent:@"book.temp"];

//下载链接

NSURL *url = [NSURL URLWithString:@"http://cnread.net/cnread1/lszl/s/simaguang/zztj/zztj.zip"];

//创建请求

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

//设置代理,别忘了在头文件里添加ASIHTTPRequestDelegate协议

request.delegate = self;

//设置下载路径

[request setDownloadDestinationPath:downloadPath];

//设置缓存路径

[request setTemporaryFileDownloadPath:tempPath];

//设置支持断点续传

[request setAllowResumeForFileDownloads:YES];

//下载进度代理可以直接用UIProgressView对象,它会自动更新,如果你想做更多的处理

//就必须用我们自定义的类,只要我们的类里实现了setPorgress:方法

request.downloadProgressDelegate = self;

//将请求添加到之前创建的队列里,这时请求已经开始执行了

//队列会retain添加进去的请求

[queue addOperation:request];

}

由于我们没有设置代理方法,request会执行下列默认代理方法:

//请求开始

- (void)requestStarted:(ASIHTTPRequest *)request;

//请求收到响应的头部,主要包括文件大小信息,下面会用到

- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders;

//请求将被重定向

- (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL;

//请求完成

- (void)requestFinished:(ASIHTTPRequest *)request;

//请求失败

- (void)requestFailed:(ASIHTTPRequest *)request;

//请求已被重定向

- (void)requestRedirected:(ASIHTTPRequest *)request;

——————————————————————————————————————————

下面是我们对头部信息的处理

- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders

{

NSLog(@”%@”,responseHeaders);

if (fileLength == 0) {

fileLength = request.contentLength/1024.0/1024.0;

totalPro.text = [NSString stringWithFormat:@"%.2fM",fileLength];

}

}

这是打印的结果:

{

“Accept-Ranges” = bytes;

“Content-Length” = 4380152;

“Content-Type” = “application/x-zip-compressed”;

Date = “Fri, 25 Nov 2011 11:43:20 GMT”;

Etag = “\”16d81c5cba6c71:78c\”";

“Last-Modified” = “Sun, 03 Jun 2007 18:16:52 GMT”;

Server = “Microsoft-IIS/6.0″;

“X-Powered-By” = “ASP.NET”;

}

我们可以从中看到文件大小等一些请求信息,这时request自己也知道了文件大小,所以我们直接使用request的contentLength属性,放心,大小是一样的!

经过测试,缓存文件是在收到头部后创建的。

——————————————————————————————————————————

这是处理进度的方法(request会自动调用该方法):

- (void)setProgress:(float)newProgress

{

progressView.progress = newProgress;

currentPro.text = [NSString stringWithFormat:@"%.2fM",fileLength*newProgress];

}

这样我们就可以看到进度了:

界面比较简陋,见笑了。。。

——————————————————————————————————————————

下面是我们的暂停方法

- (IBAction)pauseDownload

{

//operations方法返回队列里的所有请求,但我们只有一个请求

ASIHTTPRequest *request = [[queue operations] objectAtIndex:0];

//取消请求

[request clearDelegatesAndCancel];

}

你可能注意到了一个问题,因为我们的队列里只有一个请求,所以很容易获取。如果请求多了,我们应该怎么区分队列里的请求呢?有两个方法:

  1. 设置request的tag属性,就像UIView的tag一样方便,但是扩展性不强;
  2. 设置request的userInfo属性,它是个NSDictionary对象,下面不用我说了吧。

还有一件事,我们使用了clearDelegatesAndCancel方法来取消请求,我们本可以用cancel方法来达到同样的目的,但后者会使request触发代理方法requestFailed:,而前者会首先重置request的所有代理然后执行cancel方法,所以不会触发代理方法。

这里还要说一下,如果你的request代理在request被取消之前释放,那么代理方法被触发的时候就会crash!如果必须释放你的代理,请确定执行了clearDelegatesAndCancel方法!

还应该注意,这里说是暂停,其实request已经完全被取消了!下面说说断点续传是怎么回事。

其实,断点续传的功能我们在上面的代码里已经实现了。不信?

因为我们之前开启了断点续传,并且设置了缓存路径,所以request取消时就会在缓存文件里打断点,当我们在次执行上面的startDownload方法时,缓存路径还是之前的缓存路径,request会自动从缓存文件中的断点后开始下载,头部中的文件大小值也是从断点之后开始算的。神奇吧,ASIHTTPRequest已经为你打点好了一切。

继续,当请求完成时,也就是我们的文件已经下载好了的时候,下载好的文件会在我们之前指定的下载路径下生成,同时缓存文件会被删除,具体谁先谁后目前还没有弄清楚。

——————————————————————————————————————————

现在我们的压缩文件已经下载好了,可怎么打开呢,双击?NO,继续:

为了使用解压缩,我引用了第三方类库:

解压缩的代码如下:

- (IBAction)unzipFile

{

//初始化Documents路径

NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

//创建文件夹路径,这将是解压的目的路径

unzipPath = [[path stringByAppendingPathComponent:@"bookUnzip"] retain];

//创建解压器

ZipArchive *unzip = [[ZipArchive alloc] init];

if ([unzip UnzipOpenFile:downloadPath]) {

//解压

BOOL result = [unzip UnzipFileTo:unzipPathoverWrite:YES];

if (result) {

NSLog(@”解压成功!”);

}

[unzip UnzipCloseFile];

}

[unzip release];

}

OK!解压成功,现在应该可以看到解压后的文件了:

参考:

ASIHttpRequest:创建队列、下载请求、断点续传、解压缩的更多相关文章

  1. ASIHTTPRequest 详解, http 请求终结者

    转:http://www.cnblogs.com/chen1987lei/archive/2011/06/07/2074636.html ASIHTTPRequest是一款极其强劲的HTTP访问开源项 ...

  2. ASINetworkQueue 队列下载

    我们通过一个例子介绍一下请求队列使用,我们设计了一个应用,用户点击GO按钮从服务器同时下载两张图片显示在画面中. 我们直接看看主视图控制器ViewController.h代码如下: #import “ ...

  3. OKDownload 下载框架 断点续传 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. ios 后台下载,断点续传总结

    2018年12月05日 16:09:00 weixin_34101784 阅读数:5 https://blog.csdn.net/weixin_34101784/article/details/875 ...

  5. WorldWind源码剖析系列:下载请求类DownloadRequest

    下载请求类DownloadRequest是各种下载请求的抽象基类,先派生出网络下载请求类WebDownloadRequest,再派生出地理空间下载请求类GeoSpatialDownloadReques ...

  6. Android 多线程下载,断点续传,线程池

    你可以在这里看到这个demo的源码: https://github.com/onlynight/MultiThreadDownloader 效果图 这张效果图是同时开启三个下载任务,限制下载线程数量的 ...

  7. Android开发之多线程下载、断点续传、进度条和文本显示

    代码实现了在Android环境下的多线程下载.断点续传.进度条显示和文本显示百分数: import java.io.BufferedReader; import java.io.File; impor ...

  8. Java开发之多线程下载和断点续传

    代码实现了多线程下载和断点续传功能 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...

  9. java多线程下载和断点续传

    java多线程下载和断点续传,示例代码只实现了多线程,断点只做了介绍.但是实际测试结果不是很理想,不知道是哪里出了问题.所以贴上来请高手修正. [Java]代码 import java.io.File ...

随机推荐

  1. Android获取屏幕分辨率及DisplayMetrics简介

    Android 可设置为随着窗口大小调整缩放比例,但即便如此,手机程序设计人员还是必须知道手机屏幕的边界,以避免缩放造成的布局变形问题. 手机的分辨率信息是手机的一项重要信息,很好的是,Android ...

  2. QT程序启动界面的使用

    当程序的初始化工作比较多,程序可能启动较长时间后,窗口才会显示出来,用户没准会抱怨程序响应的慢. 为了改善用户体验,最好在程序初始化这段时间显示logo,或者其他信息提示用户程序已启动.QT提供了QS ...

  3. opencv和javacv版本不一致

    Exception in thread "main" java.lang.UnsatisfiedLinkError: no jniopencv_highgui in java.li ...

  4. Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)

    工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类.工厂模式的形态工厂模式主要用一下几种形态:1:简单工厂(Simple Factory).2:工厂方法(Factory M ...

  5. sql server 系统表系统视图 及作用说明

    sql server 系统视图,可分为: 目录视图   兼容性视图    动态管理视图和函数    信息架构视图    复制视图 系统表: sysaltfiles主数据库 保存数据库的文件 sysch ...

  6. springmvc入门详解

    首先,我们先写一个入门小案例,先熟悉一下springmvc是什么,了解一下springmvc的运行流程,对加强springmvc的深层理解有很大帮助 .第一步,创建一个maven项目: <?xm ...

  7. 根据id查询数据(向前台返回json格式的数据)

    /** *@description 根据主键查询Bean */ @RequestMapping(value="/getBean/{getId}") public void getB ...

  8. 安装Node.js

    1.window下安装Node.js 安装git,方便使用命令行. 网址:http://www.git-scm.com/download/ 下载后直接安装即可 接着安装Node.js https:// ...

  9. 统计"面"要素中"点"要素的个数.

    步骤 1,创建字段 IFields /// <summary> /// 创建:"面"-"点数"的字段. /// </summary> / ...

  10. nginx log日志分割

    @echo offrem 备份并根据时间重命名错误日志文件set "cmdstr=move E:\nginx\logs\error.log E:\nginx\logs\error%date: ...