iOS与Java服务器GZip压缩问题

昨天搞了一天的GZip压缩,试了三种方式(libz库,ZipArchive,ASIHttpRequest),一开始都不成功。
理论上三个应该都能用的,但我都不行。等我试到第三种方式的时候才知道,不是我的问题,而是后台的问题(Java端输出方式一会再说)。
今天就总结一下,写写iOS与Java服务器获取压缩数据的方法吧。
一、客户端-服务端数据压缩解压流程(ASIHttpRequest)
客户端生成request,设置header允许使用压缩("Accept-Encoding","gzip"),即是告诉服务器,客户端支持压缩,但凡可以压缩的服务器,尽管来吧!服务器收到这个header,如果它支持压缩,可以通过压缩方式输出数据,然后再写入response的header("Content-Encoding","gzip")
1.以ASIHttpRequest为例,代码如下:
    NSURL* requestURL = [NSURL URLWithString:_listURL];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:requestURL];
    // 默认为YES, 你可以设定它为NO来禁用gzip压缩
    [request setAllowCompressedResponse:YES];
    [request setDelegate:self];
    [request startAsynchronous];
如果是普通的URLRequest,只要:
    request.setHeader("Accept-Encoding","gzip");
2.服务器端返回:
    response.setHeader("Content-Encoding","gzip");
3.客户端响应,同样以ASIHttpRequest为例(此例传输的是json数据,我还使用了SBJson解析一下):
- (void)requestFinished:(ASIHTTPRequest *)request{
    NSString *jsonString = @"";
    SBJsonParser* jsonParser = [[SBJsonParser alloc] init];
    NSMutableDictionary *jsonDictionary = nil;
   
    BOOL dataWasCompressed = [request isResponseCompressed]; // 响应是否被gzip压缩过?
    if (dataWasCompressed) {
        NSData *uncompressedData = [request responseData]; // 解压缩后的数据
        NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
        jsonString = [[NSString alloc]initWithData:uncompressedData encoding:enc];
        jsonDictionary = [jsonParser objectWithString:jsonString error:nil];
        [jsonString release];

    } else {
        jsonString = [request responseString];
        jsonDictionary = [jsonParser objectWithString:jsonString error:nil];
    }
   
    self._tableDict = jsonDictionary;
    [jsonParser release];
    [self loadTableDict];
   
    [self release];
}
附上一篇非常详细的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换成变量名):
#include 

@implementation NSData (DDData)

- (NSData *)gzipInflate
{
 if ([self length] == 0) return self;

 unsigned full_length = [self length];
 unsigned half_length = [self length] / 2;

 NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
 BOOL done = NO;
 int status;

 z_stream strm;
 strm.next_in = (Bytef *)[self bytes];
 strm.avail_in = [self length];
 strm.total_out = 0;
 strm.zalloc = Z_NULL;
 strm.zfree = Z_NULL;



 if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;

 while (!done)
 {
  // Make sure we have enough room and reset the lengths.
  if (strm.total_out >= [decompressed length])
   [decompressed increaseLengthBy: half_length];
  strm.next_out = [decompressed mutableBytes] + strm.total_out;
  strm.avail_out = [decompressed length] - strm.total_out;
  
  // Inflate another chunk.

status = inflate (&strm, Z_SYNC_FLUSH);

  if (status == Z_STREAM_END) done = YES;

  else if (status != Z_OK) break;

 }

 if (inflateEnd (&strm) != Z_OK) return nil;

 // Set real length.
 if (done)
 {
  [decompressed setLength: strm.total_out];

return [NSData dataWithData: decompressed];
 }
 else return nil;
}



附上一篇非常详细的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数据savetofile,然后再处理,理论上是可行的,但是由于服务器有误,获取的数据不对,所以我怎么都解压不成功!!!!
示例如下:
Objective-C class used to zip / unzip compressed zip file.

Usage:
Add all the files to you project, and and framework libz.1.2.3.dylib.

include ZipArchive.h using #import "ZipArchive/ZipArchive.h"

* create zip file
ZipArchive* zipFile = [[ZipArchive alloc] init];
[zipFile CreateZipFile2:@"zipfilename"]; // A
OR
[[zipFile CreateZipFile2:@"zipfilename" Password:@"your password"];// if password needed,
                                   //empty password will get same result as A

[zipFile addFileToZip:@"fullpath of the file" newname:@"new name of the file without path"];
....add any number of files here
[zipFile CloseZipFile2];
[zipFile release]; // remember to release the object

* unzip compressed file
ZipArchive* zipFile = [[ZipArchive alloc] init];
[zipFile UnzipOpenFile:@"zip file name"]; // B (the zip got no password)
OR
[zipFile UnzipOpenFile:@"zip file name" Password:@"password" ];

[zipFile UnzipFileTo:@"output path" overwrite:YES];
[zipFile UnzipCloseFile];
[zipFile release];
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值