【问题标题】:Z_BUF_ERROR -5 while trying to decompress zlib data尝试解压缩 zlib 数据时 Z_BUF_ERROR -5
【发布时间】:2012-12-13 20:45:31
【问题描述】:

我正在尝试使用 ObjectiveZlib 示例代码中的 dataByDecompressingData: 方法解压缩一些 zlib 数据,我在转换为与 Objective-c 而非 c++ 一起使用时得到了一些帮助。代码如下

- (NSData*) dataByDecompressingData:(NSData*)data{
    Byte* bytes = (Byte*)[data bytes];
    NSInteger len = [data length];
    NSMutableData *decompressedData = [[NSMutableData alloc] initWithCapacity:COMPRESSION_BLOCK];
    Byte* decompressedBytes = (Byte*) malloc(COMPRESSION_BLOCK);

    z_stream stream;
    int err;
    stream.zalloc = (alloc_func)0;
    stream.zfree = (free_func)0;
    stream.opaque = (voidpf)0;

    stream.next_in = bytes;
    err = inflateInit(&stream);
    CHECK_ERR(err, @"inflateInit");

    while (true) {
        stream.avail_in = len - stream.total_in;
        stream.next_out = decompressedBytes;
        stream.avail_out = COMPRESSION_BLOCK;
        err = inflate(&stream, Z_NO_FLUSH);
        [decompressedData appendBytes:decompressedBytes length:(stream.total_out-[decompressedData length])];
        if(err == Z_STREAM_END)
            break;
        CHECK_ERR(err, @"inflate");
    }

    err = inflateEnd(&stream);
    CHECK_ERR(err, @"inflateEnd");

    free(decompressedBytes);
    return decompressedData;
}

一旦运行,我就会得到 Z_BUF_ERROR,我已经阅读了 here,我知道它指的是 ASIHTTPReqest,但我认为可能正在使用 xcode 提供的相同 zlib 类进行解压缩,他们说这是大小错误由于空间问题,Buffer 无法处理文件的解压。

我不完全确定这是否正确,他们提供了两种解决方案来修复,第一种是拆分数据包……这不是 imo 的选项,另一件事是增加缓冲区大小。 .我在想A,我怎么能这样呢? B、有没有更好的第三种选择?

任何帮助将不胜感激。

【问题讨论】:

    标签: objective-c ios zlib


    【解决方案1】:

    请参考http://www.zlib.net/zlib_how.html

    Z_BUF_ERROR 将在下面进一步解释,但只要说这只是 inflate() 不能消耗更多输入或产生更多输出的指示就足够了。可以使用更多输出空间或更多可用输入再次调用 inflate(),这将在此代码中。

    我看到的一些错误:

    1/ 每次你设置stream.next_in,你也应该设置stream.avail_in。请注意,当您不提供下一个输入块时,不应更改 stream.avail_in。在调用inflateInit 之前设置初始avail_in 可能是个好主意。

    2/ 使用inflateInit2(&stream, -MAX_WBITS) 可能是个好主意。注意inflateInit的普通版本不检查数据的压缩类型(gzip或zlib),如果它选择gzip,你的解压将失败。

    (应该可以工作,无需测试即可编写)

    -(NSData*)decompressData:(NSData*)compressedData {
        z_stream stream;
    
        stream.zalloc = Z_NULL;
        stream.zfree = Z_NULL;
        stream.opaque = Z_NULL;
    
        //we set the input, no need to change the values later
        stream.next_in = (Bytef *) [compressedData bytes];
        stream.avail_in = compressedData.length;  
    
        int result = inflateInit2(&stream, -MAX_WBITS);
    
        if (result != Z_OK) {
            return nil;
        }
    
        NSMutableData* uncompressedData = [NSMutableData data];
        //make buffer big enough - 128KB
        int bufferLength = 128 * 1024;
        char *buffer = malloc(bufferLength);
    
        while (true) {
            stream.next_out = buffer;
            stream.avail_out = bufferLength;
    
            //calling with Z_FINISH because we already have all the input
            result = inflate(&stream, Z_FINISH);
    
            if (result != Z_OK && result != Z_STREAM_END) {
                 inflateEnd(&stream);
                 free(buffer);
                 return nil;
            }
    
            [uncompressedData appendBytes:buffer length:(bufferLength - stream.avail_out)];
    
            if (result == Z_STREAM_END) {
                break;
            }
        }
    
    
        inflateEnd(&stream);
        free(buffer);
    
        return uncompressedData;
    }
    

    【讨论】:

    • 好的,谢谢你的回复,我会看看你刚才提到的事情。希望我能弄清楚一些。这是我以前做过的任何事情的外缘。
    • 啊.. 我已经尝试了所有我能想到的 atm.. 仍然没有运气尝试与服务器开发人员交谈,看看是否有任何问题导致此问题。
    • 哇,非常感谢!效果很好!!!谢天谢地.. 一天半的时间:P 为帮助欢呼!
    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多