iPhone中的ZLib无法解压数据

7
我正在尝试在iPhone中使用Zlib来解压数据,但它总是报错"Invalid header Check"。
我在Java中使用以下内容进行数据压缩:
实现方式:标准的Java实现Zlib
压缩器:java.util.zip.Deflater 版本号:1.45, 04/07/06
压缩级别:BEST_COMPRESSION
在iPhone中,以下是解压代码:
- (NSData *)zlibInflate
{
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 (inflateInit (&strm) != 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) {
        NSLog(@"%s", strm.msg);
        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;
}

以下是一个压缩字符串的示例:
xÚÝUko²Jþ~?­ó?¥¾?¤?©?´ÚjCMX,Òµ?ª?µßVX¹È­?¿.øë_?¯¶ZÏ%íùxHH&Ã<ÏÌ3ÌÎ
@2.ðE?ºqþpéEzÏ09IoÒ?ª? ?®?£àÌönì$brÛ#fl95?¿»a//Tçáò?¢?¿½
µ©ÊÃÉPÔ¼:8y¦ý.äÎ?µ?¥?¼y?©ã¯9ö?¥½?¢±ÝûwÛ?§ãga?©á8?¨?­m\Õ?»6,'Îe?¬}(L}7ÆÅ6#gJ(¥7´s?¬d.ó,Ë°¦prßýÕÖ? 

以下是压缩器的函数:
public static byte[] compress(String s) {
       Deflater comp = new Deflater();
       //comp.setLevel(Deflater.BEST_COMPRESSION);

       comp.setInput(s.getBytes());

       comp.finish();
       ByteArrayOutputStream bos = new ByteArrayOutputStream(s.length());

       // Compress the data
       byte[] buf = new byte[1024];
       try {
            while (!comp.finished()) {
                  int count = comp.deflate(buf);
                  bos.write(buf, 0, count);
            }
            bos.close();
       } catch (Exception e) {
            //Log.d(TAG, e.getMessage());
            e.printStackTrace();
       }

       // Get the compressed data
       byte[] compressedData = bos.toByteArray();

       // put in this fix for Symbol scanners
       byte[] compressedDataForSymbol = mungeForSymbol(compressedData);
       /*
       * byte[] decompressedDataForSymbol =
       * decompressedDataAfterSymbol(compressedDataForSymbol); // check they
       * are the same for(int i=0;i<compressedData.length;i++) { if
       * (compressedData[i] != decompressedDataForSymbol[i]) {
       * //System.out.println("Error at " + i); } }
       */
       return compressedDataForSymbol;
       // return s.getBytes();

 }

我遇到了同样的问题... - nullmicgo
你能添加Java压缩代码作为参考吗?你如何调用Deflater构造函数? - Sulthan
请查看上面的 Java 函数。 - user2020313
1
数据从Java到iOS的传输过程中是否可能会损坏?mungeForSymbol函数是用来做什么的? - Sulthan
你确定你的压缩数据有适当的zlib头吗?请将前两个字节与规格进行比较。 - dwery
1个回答

2
使用默认压缩级别的Java Deflater会创建带有头部的输出编码数据,其中第一个字节为0x78,第二个字节为0x9c。在IOS中不使用这些。只需删除前两个字节并尝试在IOS中进行Inflate即可进行解压缩。它应该可以工作。 我曾经遇到过同样的问题,但我想要从IOS(压缩)获取数据并将其解压缩到Android中。

在Java中,您可以使用new Deflater(Deflater.DEFAULT_COMPRESSION,true),它不会添加该标头。 - algrid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接