• iOS与服务器端 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数据
    save to file,然后再处理,理论上是可行的,但是由于服务器有误,获取的数据不对,所以我怎么都解压不成功!!!!
    示例如下: 

    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];
    

      

  • 相关阅读:
    项目编译
    sqlserver查列名
    list<>初始化赋值两种方式
    看到一句很不错的话
    typescript
    vscode里div等html标签代码补全
    JavaScript 基于原型链的继承
    大数据系列01:大数据离线计算平台hadoop集群搭建和本地环境配置实践
    java数据类型
    计算机基础及java基础
  • 原文地址:https://www.cnblogs.com/ccguo/p/3962404.html
Copyright © 2020-2023  润新知