2013-04-29 36 views
1

我有一個Java字符串,我想用GZip編碼,通過套接字將編碼字符串發送到iOS應用程序並在那裏解碼字符串。這是行不通的,因爲當我在應用程序端解碼它時,我沒有得到正確的字符串(相反,當我執行數據的NSLog時,我得到3個問號)。在Java中,我使用GZIPOutputStream對數據進行編碼,在iOS中,我使用NSData上的類別對數據進行解碼。在Java中膨脹GZip字符串並在iOS中再次泄氣

這是我在Java中:

// gzip the string 
sb = new StringBuilder("the quick brown fox jumps over the lazy dog"); 
ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); 
GZIPOutputStream gzip = new GZIPOutputStream(outBytes); 
gzip.write(sb.toString().getBytes()); 
gzip.finish(); 
gzip.close(); 
outBytes.close(); 
System.out.println("Gzipped string: " + outBytes.toString()); 

out.print(outBytes.toString()); 
out.flush(); 

出在哪裏是我的插座的輸出流的PrintWriter。

在iOS中,我使用以下類別對數據進行解碼:

+ (NSData *)gzipDeflate:(NSData*)data 
{ 
    if ([data length] == 0) return data; 

    z_stream strm; 

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

    // Compresssion Levels: 
    // Z_NO_COMPRESSION 
    // Z_BEST_SPEED 
    // Z_BEST_COMPRESSION 
    // Z_DEFAULT_COMPRESSION 

    if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil; 

    NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion 

    do { 
     if (strm.total_out >= [compressed length]) 
      [compressed increaseLengthBy: 16384]; 

     strm.next_out = [compressed mutableBytes] + strm.total_out; 
     strm.avail_out = [compressed length] - strm.total_out; 

     deflate(&strm, Z_FINISH); 

    } while (strm.avail_out == 0); 

    deflateEnd(&strm); 

    [compressed setLength: strm.total_out]; 
    return [NSData dataWithData:compressed]; 
} 

在iOS的客戶端報文的閱讀:

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 
{ 
    if(!readedData) readedData = [data mutableCopy]; 
    else [readedData appendData:data]; 
    // and some more code ... 
} 

當我readed一切,我嘗試解碼數據:

NSString *dataString = [[NSString alloc] initWithData:[NSData gzipDeflate:data] encoding:NSStringEncodingConversionAllowLossy]; 
NSLog(@"data string: %@", dataString); 

我不知道我在做什麼錯在這裏。是否Java和iOS使用其他解碼協議?

+0

可能重複[Java:創建GZIPInputStream時出錯:不是GZIP格式](http://stackoverflow.com/questions/14466840/java-error-creating-a-gzipinputstream-not-in-gzip-format) – jarnbjo 2013-04-29 11:44:45

回答

2

您使用充氣進行解壓縮,而不是放氣。

0

我能夠通過使用由Mark建議的gzip充氣來解決上述問題。但請確保您使用創始人自己寫的正確的gzip充氣(https://stackoverflow.com/a/17822217/840384)。然後檢查您在服務器端使用的編碼類型。有一些像「/」這樣的符號沒有正確解碼,導致無效的gzip流。所以採取編碼文件,並與NSData解碼文件進行比較,並進行必要的更改。

讓我知道你是否需要任何其他幫助在iOS端解碼。我能夠實現60%以上的通過網絡交換的數據壓縮。從iOS應用程序角度來看,性能有了巨大的提升