iOS 데이터 요청 GZip 데이터 압축 및 압축 해제 문제
클라이언트가 request를 생성하고 header가 압축을 사용할 수 있도록 설정합니다("Accept-Encoding", "gzip"). 즉, 서버에 클라이언트가 압축을 지원하지만 압축할 수 있는 서버는 얼마든지 오세요!서버에서 이 헤더를 받았습니다. 만약 압축을 지원한다면 압축 방식으로 데이터를 출력한 다음response의 헤더를 쓸 수 있습니다. ("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");
libz 라이브러리 libz 라이브러리는 공식적인 라이브러리입니다. ASIHttpRequest도 이 라이브러리로 압축을 풀었습니다. 우리가 압축된 데이터 데이터를 얻은 후에 (방법은 위와 유사하지만
일반적인 데이터 응답), 이런 방법으로 데이터를 압축할 수 있으며, 압축 해제 방법은 다음과 같다.
데이터 압축 참조:http://www.clintharris.net/2009/how-to-gzip-data-in-memory-using-objective-c/
데이터 압축 해제 참조: ASIHttpRequest 라이브러리 파일: ASIDataDecompressor.m
//  :GzipUtility.h
#import 
@interface GzipUtility : NSObject
        //  
        + (NSData *)compressData:(NSData*)uncompressedData;  
        //  
        + (NSData *)decompressData:(NSData *)compressedData;
@end
//  :GzipUtility.m
#import "GzipUtility.h"
#import "zlib.h"
@implementation GzipUtility
+(NSData*) compressData: (NSData*)uncompressedData  {  
    /* 
     Special thanks to Robbie Hanson of Deusty Designs for sharing sample code 
     showing how deflateInit2() can be used to make zlib generate a compressed 
     file with gzip headers: 
     http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html 
     */  
    
    if (!uncompressedData || [uncompressedData length] == 0)  {  
        NSLog(@"%s: Error: Can't compress an empty or null NSData object.", __func__);  
        return nil;  
    }  
    
    /* Before we can begin compressing (aka "deflating") data using the zlib 
     functions, we must initialize zlib. Normally this is done by calling the 
     deflateInit() function; in this case, however, we'll use deflateInit2() so 
     that the compressed data will have gzip headers. This will make it easy to 
     decompress the data later using a tool like gunzip, WinZip, etc. 
     
     deflateInit2() accepts many parameters, the first of which is a C struct of 
     type "z_stream" defined in zlib.h. The properties of this struct are used to 
     control how the compression algorithms work. z_stream is also used to 
     maintain pointers to the "input" and "output" byte buffers (next_in/out) as 
     well as information about how many bytes have been processed, how many are 
     left to process, etc. */  
    z_stream zlibStreamStruct;  
    zlibStreamStruct.zalloc    = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so  
    zlibStreamStruct.zfree     = Z_NULL; // that when we call deflateInit2 they will be  
    zlibStreamStruct.opaque    = Z_NULL; // updated to use default allocation functions.  
    zlibStreamStruct.total_out = 0; // Total number of output bytes produced so far  
    zlibStreamStruct.next_in   = (Bytef*)[uncompressedData bytes]; // Pointer to input bytes  
    zlibStreamStruct.avail_in  = [uncompressedData length]; // Number of input bytes left to process  
    
    /* Initialize the zlib deflation (i.e. compression) internals with deflateInit2(). 
     The parameters are as follows: 
     
     z_streamp strm - Pointer to a zstream struct 
     int level      - Compression level. Must be Z_DEFAULT_COMPRESSION, or between 
     0 and 9: 1 gives best speed, 9 gives best compression, 0 gives 
     no compression. 
     int method     - Compression method. Only method supported is "Z_DEFLATED". 
     int windowBits - Base two logarithm of the maximum window size (the size of 
     the history buffer). It should be in the range 8..15. Add 
     16 to windowBits to write a simple gzip header and trailer 
     around the compressed data instead of a zlib wrapper. The 
     gzip header will have no file name, no extra data, no comment, 
     no modification time (set to zero), no header crc, and the 
     operating system will be set to 255 (unknown). 
     int memLevel   - Amount of memory allocated for internal compression state. 
     1 uses minimum memory but is slow and reduces compression 
     ratio; 9 uses maximum memory for optimal speed. Default value 
     is 8. 
     int strategy   - Used to tune the compression algorithm. Use the value 
     Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data 
     produced by a filter (or predictor), or Z_HUFFMAN_ONLY to 
     force Huffman encoding only (no string match) */  
    int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);  
    if (initError != Z_OK)  
    {  
        NSString *errorMsg = nil;  
        switch (initError)  
        {  
            case Z_STREAM_ERROR:  
                errorMsg = @"Invalid parameter passed in to function.";  
                break;  
            case Z_MEM_ERROR:  
                errorMsg = @"Insufficient memory.";  
                break;  
            case Z_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);  
        [errorMsg release];  
        return nil;  
    }  
    
    // Create output memory buffer for compressed data. The zlib documentation states that  
    // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes.  
    NSMutableData *compressedData = [NSMutableData dataWithLength:[uncompressedData length] * 1.01 + 12];  
    
    int deflateStatus;  
    do  
    {  
        // Store location where next byte should be put in next_out  
        zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out;  
        
        // Calculate the amount of remaining free space in the output buffer  
        // by subtracting the number of bytes that have been written so far  
        // from the buffer's total capacity  
        zlibStreamStruct.avail_out = [compressedData length] - zlibStreamStruct.total_out;  
        
        /* deflate() compresses as much data as possible, and stops/returns when 
         the input buffer becomes empty or the output buffer becomes full. If 
         deflate() returns Z_OK, it means that there are more bytes left to 
         compress in the input buffer but the output buffer is full; the output 
         buffer should be expanded and deflate should be called again (i.e., the 
         loop should continue to rune). If deflate() returns Z_STREAM_END, the 
         end of the input stream was reached (i.e.g, all of the data has been 
         compressed) and the loop should stop. */  
        deflateStatus = deflate(&zlibStreamStruct, Z_FINISH);  
        
    } while ( deflateStatus == Z_OK );        
    
    // Check for zlib error and convert code to usable error message if appropriate  
    if (deflateStatus != Z_STREAM_END)  
    {  
        NSString *errorMsg = nil;  
        switch (deflateStatus)  
        {  
            case Z_ERRNO:  
                errorMsg = @"Error occured while reading file.";  
                break;  
            case Z_STREAM_ERROR:  
                errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL).";  
                break;  
            case Z_DATA_ERROR:  
                errorMsg = @"The deflate data was invalid or incomplete.";  
                break;  
            case Z_MEM_ERROR:  
                errorMsg = @"Memory could not be allocated for processing.";  
                break;  
            case Z_BUF_ERROR:  
                errorMsg = @"Ran out of output buffer for writing compressed bytes.";  
                break;  
            case Z_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);  
        [errorMsg release];  
        
        // Free data structures that were dynamically created for the stream.  
        deflateEnd(&zlibStreamStruct);  
        
        return nil;  
    }  
    
    // Free data structures that were dynamically created for the stream.  
    deflateEnd(&zlibStreamStruct);  
    
    [compressedData setLength: zlibStreamStruct.total_out];  
    
    return compressedData;  
}  
+ (NSData *)decompressData:(NSData *)compressedData {
    z_stream zStream;
    zStream.zalloc = Z_NULL;
    zStream.zfree = Z_NULL;
    zStream.opaque = Z_NULL;
    zStream.avail_in = 0;
    zStream.next_in = 0;
    int status = inflateInit2(&zStream, (15+32));
    
    if (status != Z_OK) {
        return nil;
    }
    
    Bytef *bytes = (Bytef *)[compressedData bytes];
    NSUInteger length = [compressedData length];
    
    NSUInteger halfLength = length/2;
    NSMutableData *uncompressedData = [NSMutableData dataWithLength:length+halfLength];
    
    zStream.next_in = bytes;
    zStream.avail_in = (unsigned int)length;
    zStream.avail_out = 0;
    
    NSInteger bytesProcessedAlready = zStream.total_out;
    while (zStream.avail_in != 0) {
        
        if (zStream.total_out - bytesProcessedAlready >= [uncompressedData length]) {
            [uncompressedData increaseLengthBy:halfLength];
        }
        
        zStream.next_out = (Bytef*)[uncompressedData mutableBytes] + zStream.total_out-bytesProcessedAlready;
        zStream.avail_out = (unsigned int)([uncompressedData length] - (zStream.total_out-bytesProcessedAlready));
        
        status = inflate(&zStream, Z_NO_FLUSH);
        
        if (status == Z_STREAM_END) {
            break;
        } else if (status != Z_OK) {
            return nil;
        }
    }
    
    status = inflateEnd(&zStream);
    if (status != Z_OK) {
        return nil;
    }
    
    [uncompressedData setLength: zStream.total_out-bytesProcessedAlready];  // Set real length
    return uncompressedData;    
}
@end 이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.