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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM