You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS解压Windows生成的gzip文件时触发UNZ_BADZIPFILE(-103)错误求助

问题

我们用C# Windows控制台应用,通过System.IO.Compression.GZipStream压缩SQLite文件,生成的.gzip文件上传到服务器后供iOS端下载。现在遇到的问题是:iOS应用用SSZipArchive库解压时触发UNZ_BADZIPFILE(-103)错误,但在Mac上手动下载该文件后,用SSZipArchive能正常解压。想问是否需要做编码处理,让iOS识别Windows生成的gzip文件?

C# 压缩代码

FileInfo fileToBeGZipped = new FileInfo(filePath);
FileInfo gzipFileName = new FileInfo(string.Concat(fileToBeGZipped.FullName, ".gzip"));

using (FileStream fileToBeZippedAsStream = fileToBeGZipped.OpenRead())
{
    using (FileStream gzipTargetAsStream = gzipFileName.Create())
    {
        using (GZipStream gzipStream = new GZipStream(gzipTargetAsStream, CompressionMode.Compress))
        {
            try
            {
                fileToBeZippedAsStream.CopyTo(gzipStream);                                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

iOS 解压代码

if (![SSZipArchive unzipFileAtPath:[downloadedStoreURL path] toDestination:[destinationURL path] delegate:nil]) {
    CLHLog(@"Couldn't unzip downloaded database");
    return NO;
}

错误信息

Error listing contents of archive: Error Domain=UZKErrorDomain Code=-103 "Bad zip file" UserInfo={NSLocalizedFailureReason=Bad zip file, NSLocalizedRecoverySuggestion=Error opening zip file /var/mobile/Containers/Data/Application/1DD4F888-0171-42D0-AC69-E0D497AC3943/Library/InspectionForms_compresed.sqlite.gzip, NSURL=file:///var/mobile/Containers/Data/Application/1DD4F888-0171-42D0-AC69-E0D497AC3943/Library/InspectionForms_compresed.sqlite.gzip, NSLocalizedDescription=Bad zip file}

解决方案

这个问题不需要额外编码处理,核心矛盾是格式适配问题:

  1. SSZipArchive的定位是处理ZIP格式,而非GZIP
    GZip和Zip是两种完全不同的压缩标准:

    • 你的C#代码生成的是单文件GZIP压缩包,属于流式压缩格式
    • SSZipArchive主打多文件ZIP归档解压,Mac端环境对GZIP的兼容逻辑更宽松,iOS端的底层实现则对非ZIP格式的识别存在限制,因此报错。
  2. 直接解决方案:iOS端换用GZIP专用解压逻辑
    放弃用SSZipArchive处理GZIP文件,改用iOS原生zlib库实现解压,比如封装NSData的扩展方法:

    #import <zlib.h>
    
    @interface NSData (GZIP)
    - (NSData *)gzipInflate;
    @end
    
    @implementation NSData (GZIP)
    - (NSData *)gzipInflate {
        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 (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
        while (!done) {
            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;
    
            status = inflate (&strm, Z_NO_FLUSH);
            if (status == Z_STREAM_END) done = YES;
            else if (status != Z_OK) break;
        }
        if (inflateEnd (&strm) != Z_OK) return nil;
    
        if (done) {
            [decompressed setLength: strm.total_out];
            return decompressed;
        } else return nil;
    }
    @end
    

    调用示例:

    NSData *gzipData = [NSData dataWithContentsOfURL:downloadedStoreURL];
    NSData *uncompressedData = [gzipData gzipInflate];
    if (uncompressedData) {
        [uncompressedData writeToURL:destinationURL atomically:YES];
    } else {
        CLHLog(@"Couldn't unzip downloaded database");
        return NO;
    }
    
  3. 备选方案:C#端生成ZIP格式文件
    如果坚持要用SSZipArchive,可修改C#代码生成标准ZIP包:

    using (FileStream zipToOpen = new FileInfo("output.zip").Create())
    {
        using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
        {
            ZipArchiveEntry entry = archive.CreateEntry("InspectionForms_compresed.sqlite");
            using (FileStream fileStream = new FileInfo(filePath).OpenRead())
            using (Stream entryStream = entry.Open())
            {
                fileStream.CopyTo(entryStream);
            }
        }
    }
    

    这样iOS端用现有SSZipArchive代码即可正常解压。

内容的提问来源于stack exchange,提问作者ramdev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 13:32:02