1. 程式人生 > >iOS GZIP 字串解壓

iOS GZIP 字串解壓

   JAVA後臺,將一個base64的字串通過GZIP壓縮成了另一個字串,iOS端需要先解壓,然後轉為base64,最後轉成圖片。找到一個NSData解壓的方法,就先把字串original轉成NSdata,解壓,然後轉回字串result,這個result就是original解壓出來的字串。轉成圖片,OK。下面是程式碼。

//後臺返回的字串

       NSString * original = dict[@"imgblob"];

//字串轉NSdata,注意編碼格式

       NSData * dataGzip = [original dataUsingEncoding:NSISOLatin1StringEncoding];

//解壓

       NSData * uncompress = [LFCGzipUtillity uncompressZippedData:dataGzip];

//將解壓出來的NSdata轉成NSString(這就是後臺傳過來的字串經過解壓處理後的結果字串)

       NSString * result = [[NSString alloc] initWithData:uncompress encoding:NSISOLatin1StringEncoding];

//將這個字串(是經過base64轉碼的字串)轉為NSdata

        NSData * data =[[NSData alloc] initWithBase64EncodedString:result options:NSDataBase64DecodingIgnoreUnknownCharacters];

//NSdata轉為UIimage

        UIImage * image = [UIImage imageWithData:data];

        _sceneControlImg.image = image;

解壓方法如下 

+(NSData *)uncompressZippedData:(NSData *)compressedData  {  

if ([compressedData length] == 0) return compressedData;  

unsigned full_length = [compressedData length];  

unsigned

half_length = [compressedData length] / 2;  

NSMutableData *decompressed = [NSMutableDatadataWithLength: full_length + half_length];  

BOOL done = NO;  

int status;  

z_stream strm;  

    strm.next_in = (Bytef *)[compressedData bytes];  

    strm.avail_in = [compressedData length];  

    strm.total_out = 0;  

    strm.zalloc = Z_NULL;  

    strm.zfree = Z_NULL;  

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

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;  

        } elseif (status != Z_OK) {  

break;  

        }  

    }  

if (inflateEnd (&strm) != Z_OK) returnnil;  

// Set real length.  

if (done) {  

        [decompressed setLength: strm.total_out];  

return [NSDatadataWithData: decompressed];  

    } else {  

returnnil;  

    }  

}

另附GZIP壓縮方法:

+ (NSData *)gzipData:(NSData *)pUncompressedData

{

if (!pUncompressedData || [pUncompressedData length] == 0) {

NSLog(@"%s: Error: Can't compress an empty or nil NSData object",__func__);

returnnil;

}

z_stream zlibStreamStruct;

zlibStreamStruct.zalloc = Z_NULL;

zlibStreamStruct.zfree = Z_NULL;

zlibStreamStruct.opaque = Z_NULL;

zlibStreamStruct.total_out = 0;

zlibStreamStruct.next_in = (Bytef *)[pUncompressedData bytes];

zlibStreamStruct.avail_in = [pUncompressedData length];

int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);

if (initError != Z_OK) {

NSString *errorMsg = nil;

switch (initError) {

caseZ_STREAM_ERROR:

errorMsg = @"Invalid parameter passed in to function.";

break;

caseZ_MEM_ERROR:

errorMsg = @"Insufficient memory.";

break;

caseZ_VERSION_ERROR:

errorMsg = @"The version of zlib.h and the version of the library linked do not match.";

break;

default:

errorMsg = @"Unknown error code.";

break;

}

NSLog(@"%s:deflateInit2() Error: \"%@\" Message: \"%s\"",__func__,errorMsg,zlibStreamStruct.msg);

returnnil;

}

NSMutableData *compressedData = [NSMutableDatadataWithLength:[pUncompressedData length] * 1.01 + 21];

int deflateStatus;

do {

zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out;

zlibStreamStruct.avail_out = [compressedData length] - zlibStreamStruct.total_out;

deflateStatus = deflate(&zlibStreamStruct, Z_FINISH);

} while (deflateStatus == Z_OK);

if (deflateStatus != Z_STREAM_END

{

NSString *errorMsg = nil;

switch (deflateStatus) {

caseZ_ERRNO:

  errorMsg = @"Error occured while reading file.";

break;

caseZ_STREAM_ERROR:

  errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL).";

break;

caseZ_DATA_ERROR:

  errorMsg = @"The deflate data was invalid or incomplete.";

break;

caseZ_MEM_ERROR:

  errorMsg = @"Memory could not be allocated for processing.";

break;

caseZ_BUF_ERROR:

  errorMsg = @"Ran out of output buffer for writing compressed bytes.";

break;

caseZ_VERSION_ERROR:

  errorMsg = @"The version of zlib.h and the version of the library linked do not match.";

break

default:

  errorMsg = @"Unknown error code.";

break;

  }

NSLog(@"%s:zlib error while attempting compression: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg);

deflateEnd(&zlibStreamStruct);

returnnil;

}

deflateEnd(&zlibStreamStruct);

[compressedData setLength:zlibStreamStruct.total_out];

NSLog(@"%s: Compressed file from %d B to %d B", __func__, [pUncompressedData length], [compressedData length]);

return compressedData;

}