昨天搞了一天的GZip压缩,试了三种方式(libz库,ZipArchive,ASIHttpRequest),一开始都不成功。
理论上三个应该都能用的,但我都不行。等我试到第三种方式的时候才知道,不是我的问题,而是后台的问题(Java端输出方式一会再说)。
今天就总结一下,写写iOS与Java服务器获取压缩数据的方法吧。
一、客户端-服务端数据压缩解压流程(ASIHttpRequest)客户端生成request,
设置header允许使用压缩("Accept-Encoding","gzip"),即是告诉服务器,
客户端支持压缩,但凡可以压缩的服务器,尽管来吧!服务器收到这个header,
如果它支持压缩,可以通过压缩方式输出数据,
然后再写入response的header("Content-Encoding","gzip")
1.以ASIHttpRequest为例,代码如下:

  1. NSURL* requestURL = [NSURL URLWithString:_listURL];
  2. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:requestURL];

// 默认为YES, 你可以设定它为NO来禁用gzip压缩 [request setAllowCompressedResponse:YES];

  1. [request setDelegate:self];
  2. [request startAsynchronous];

  

如果是普通的URLRequest,只要: request.setHeader("Accept-Encoding","gzip");

2.服务器端返回: response.setHeader("Content-Encoding","gzip");

3.客户端响应,同样以ASIHttpRequest为例(此例传输的是json数据,我还使用了SBJson解析一下):

  1. - (void)requestFinished:(ASIHTTPRequest *)request{
  2. NSString *jsonString = @"";
  3. SBJsonParser* jsonParser = [[SBJsonParser alloc] init];
  4. NSMutableDictionary *jsonDictionary = nil;
  5. BOOL dataWasCompressed = [request isResponseCompressed]; // 响应是否被gzip压缩过?
  6. if (dataWasCompressed)
  7. {
  8. NSData *uncompressedData = [request responseData];
  9. // 解压缩后的数据
  10. NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  11. jsonString = [[NSString alloc]initWithData:uncompressedData encoding:enc];
  12. jsonDictionary = [jsonParser objectWithString:jsonString error:nil];
  13. [jsonString release];
  14. }else {
  15. jsonString = [request responseString];
  16. jsonDictionary = [jsonParser objectWithString:jsonString error:nil];
  17. }
  18. self._tableDict = jsonDictionary;
  19. [jsonParser release];
  20. [self loadTableDict];
  21. [self release];
  22. }

  

附上一篇非常详细的ASIHttpRequest请求Json数据教程(无GZip相关内容):
http://ios-blog.co.uk/articles/tutorials/parsing-json-on-ios-with-asihttprequest-and-sbjson/
libz库 libz库是官方的一个库,貌似ASIHttpRequest也是用这个库解压的,当我们获得压缩过的data数据以后(方法与上面类似,
只是获得了普通的data数据响应),可以使用这种方法解压数据,解压方法如下所示(如果仅仅放在当前类下面使用,传个data参数进来,
然后把self换成变量名):

  1. #include @implementation NSData (DDData)
  2. - (NSData *)gzipInflate {
  3. if ([self length] == 0)
  4. return self;
  5. unsigned full_length = [self length];
  6. unsigned half_length = [self length] / 2;
  7. NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length]; BOOL done = NO;
  8. int status;
  9. z_stream strm;
  10. strm.next_in = (Bytef *)[self bytes];
  11. strm.avail_in = [self length];
  12. strm.total_out = 0;
  13.  
  14. strm.zalloc = Z_NULL;
  15. strm.zfree = Z_NULL;
  16. if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
  17.  
  18. while (!done) { // Make sure we have enough room and reset the lengths.
  19. if (strm.total_out >= [decompressed length])
  20. [decompressed increaseLengthBy: half_length];
  21.  
  22. strm.next_out = [decompressed mutableBytes] + strm.total_out;
  23. strm.avail_out = [decompressed length] - strm.total_out;
  24. // Inflate another chunk. status = inflate (&strm, Z_SYNC_FLUSH);
  25. if (status == Z_STREAM_END)
  26. done = YES;
  27. else if (status != Z_OK)
  28. break;
  29. }
  30. if (inflateEnd (&strm) != Z_OK) return nil;
  31. // Set real length.
  32. if (done) {
  33. [decompressed setLength: strm.total_out];
  34. return [NSData dataWithData: decompressed];
  35. } else
  36. return nil;
  37. }

  

附上一篇非常详细的libz库压缩教程 http://www.clintharris.net/2009/how-to-gzip-data-in-memory-using-objective-c/

以及压缩解压教程(代码从这里拷贝的): http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html

ZipArchive 上面讲的都是Memory压缩与解压,ZipArchive主要是对文档进行处理。昨天在上述方法不成功的情况下,我把获取的data数据
save to file,然后再处理,理论上是可行的,但是由于服务器有误,获取的数据不对,所以我怎么都解压不成功!!!!
示例如下:

  1. Objective-C class used to zip / unzip compressed zip file.
  2. Usage: Add all the files to you project, and and framework libz.1.2.3.dylib.
  3.  
  4. include ZipArchive.h
  5. using #import "ZipArchive/ZipArchive.h" *
  6. create zip file
  7.  
  8. ZipArchive* zipFile = [[ZipArchive alloc] init];
  9. [zipFile CreateZipFile2:@"zipfilename"];
  10.  
  11. // A OR [[zipFile CreateZipFile2:@"zipfilename" Password:@"your password"];
  12. // if password needed, //empty password will get same result as A
  13.  
  14. [zipFile addFileToZip:@"fullpath of the file" newname:@"new name of the file without path"];
  15. // ....add any number of files here
  16. [zipFile CloseZipFile2];
  17. [zipFile release];
  18.  
  19. // remember to release the object * unzip compressed file
  20. ZipArchive* zipFile = [[ZipArchive alloc] init];
  21. [zipFile UnzipOpenFile:@"zip file name"];
  22.  
  23. // B (the zip got no password) OR [zipFile UnzipOpenFile:@"zip file name" Password:@"password" ];
  24. [zipFile UnzipFileTo:@"output path" overwrite:YES];
  25. [zipFile UnzipCloseFile];
  26. [zipFile release];

  

iOS与服务器端 GZip压缩问题的更多相关文章

  1. 专业术语:闭包、网站优化 Gzip 服务器端文件压缩

    1, 闭包:http://baike.baidu.com/view/648413.htm 2, 网站优化 Gzip 服务器端文件压缩 http://baike.baidu.com/view/96662 ...

  2. GZIP压缩优化

    使用gzip优化web应用(filter实现) 相关知识: gzip是http协议中使用的一种加密算法,客户端向web服务器端发出了请求后,通常情况下服务器端会将页面文件和其他资源,返回到客户端,客户 ...

  3. Nginx 开启gzip 压缩

    随着nginx的发展,越来越多的网站使用nginx,因此nginx的优化变得越来越重要,今天我们来看看nginx的gzip压缩到底是怎么压缩的呢? gzip(GNU-ZIP)是一种压缩技术. 经过gz ...

  4. thttpd增加gzip压缩响应报文体功能,以减少传输数据量

    thttpd thttpd是一个非常小巧的轻量级web server,它非常非常简单,仅仅提供了HTTP/1.1和简单的CGI支持,在其官方网站上有一个与其他web server(如Apache, Z ...

  5. apache启用gzip压缩方法--转载自http://www.cnblogs.com/linzhenjie/archive/2013/03/05/2943635.html

    一.gzip介绍 Gzip是一种流行的文件压缩算法,现在的应用十分广泛,尤其是在Linux平台.当应用Gzip压缩到一个纯文本文件时,效果是非常明显的,大约可以减少70%以上的文件大小.这取决于文件中 ...

  6. Nginx Gzip 压缩配置

    Nginx Gzip 压缩配置 随着nginx的发展,越来越多的网站使用nginx,因此nginx的优化变得越来越重要,今天我们来看看nginx的gzip压缩到底是怎么压缩的呢? gzip(GNU-Z ...

  7. gzip压缩JavaScript

    为了提高客户端的体验效果,RIA开发逐渐兴起.这样会项目中会充斥的大量的JavaScript代码,与此同时会消耗客户端浏览器性能.对于 Ext 实现的 one page one application ...

  8. Tomcat启用Gzip压缩

    原理简介         HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并 浏览.相对于普通的 ...

  9. 【nginx网站性能优化篇(1)】gzip压缩与expire浏览器缓存

    gzip压缩 概述 网页在服务器端经过了gzip或者其他格式的压缩后的输出明显减少了content-length字节,当访问过百万时,这些减少的字节就会变为客观的流量给节约下来;从而减轻服务器的压力以 ...

随机推荐

  1. Java for selenium(webdriver) 环境搭建

    开发环境 1. jdk1.7 2. Eclipse 3. selenium(selenium-java-2.42.2.zip) 将下载下来的 selenium-java-2.42.2.zip 解压, ...

  2. Android环境rm命令

    How can I execute all the possible unix(shell) commands in android programmatically? Android can't e ...

  3. OGRE插件设计-Texture与GLTexture

    背景: 学习OGRE,在OGRE中 Core是最小的精简逻辑集合,而真正的功能则需要插件来实现,但是作为插件应该与Core保持最小的连接,同时Core不会调用插件的接口,而动态链接库又不能直接把类连接 ...

  4. 让IE6兼容position:fixed

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. poj 3468 A Simple Problem with Integers【线段树区间修改】

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 79137   ...

  6. java第一章到第四章

    class HelloWorld{ public static void main(String [] arguments) { System.out.println("Hello Worl ...

  7. [置顶] 在Ubuntu下实现一个简单的Web服务器

    要求: 实现一个简单的Web服务器,当服务器启动时要读取配置文件的路径.如果浏览器请求的文件是可执行的则称为CGI程序,服务器并不是将这个文件发给浏览器,而是在服务器端执行这个程序,将它的标准输出发给 ...

  8. Android 系统名字、版本、API level的对应关系

    从官网上找到的,具体地址是: http://source.android.com/source/build-numbers.html Code name Version API level Lolli ...

  9. 【Android XMPP】 学习资料收集贴(持续更新)

    系列一: 基于xmpp openfire smack开发之openfire介绍和部署[1] 基于xmpp openfire smack开发之smack类库介绍和使用[2] 基于xmpp openfir ...

  10. 关于tomcat的思考

    下载文件两种方式:绿色版的.安装版的(找到jre的环境变量.配置或修改端口8080→8070) 启动完tomcat之后: 既可以虚拟目录打开(如http://localhost:8070/mldn/) ...