在c#中使用GZIP压缩,在python中解压缩失败

2024-09-30 22:28:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个流程,其中一些数据(如图像/视频)使用GZip进行压缩,如下所示:

await using var outputStream = new MemoryStream();
await using var compressionStream = new GZipStream(outputStream, CompressionMode.Compress);

await compressionStream.WriteAsync(payload);
await compressionStream.FlushAsync();

outputStream.Position = 0;
return outputStream.ToArray()

上面的代码不是我的团队提供的,但如果需要可以更改

如果我将输出转换为base64字符串,并使用以下简单代码对其进行测试解压缩,它将非常有效:

var bytes = Convert.FromBase64String("H4sIAAAAAAAACirOz01VKEmtKAEAAAD//w=="); // "some text"
using var ms = new MemoryStream(bytes);
using var ds = new GZipStream(ms, CompressionMode.Decompress);
using var output = new MemoryStream();
ds.CopyTo(output);
ds.Flush();

var result = output.ToArray();

但是,我的要求是在python脚本中获取压缩的负载,并在将其传递到另一个系统之前对其进行解压缩。我对python一点也不熟悉,所以我编写了一个非常简单的脚本:

import base64
import gzip

encodedBase64 = "H4sIAAAAAAAACirOz01VKEmtKAEAAAD//w=="
decodedBytes = base64.standard_b64decode(encodedBase64)
decompressedBytes = gzip.decompress(decodedBytes)

上述操作失败:EOFError: Compressed file ended before the end-of-stream marker was reached

我当然做过研究并找到了类似this Q&A的帖子,但没有任何帮助(例如,使用该答案在gzip.BadGzipFile: Not a gzipped file (b'\x00\x00')时失败)。其他尝试产生了不同的gzip错误


Tags: 代码newoutputvardsawaitusinggzip
1条回答
网友
1楼 · 发布于 2024-09-30 22:28:09

在读取GzipStream的输出之前,需要先释放它。Gzip有一个需要添加到流末尾的页脚,它是added by ^{}(也是由Close())但是not by ^{}。我想这是有道理的,因为在编码过程中Flush()可能会被多次调用,所以在这里添加页脚是错误的

我重写了您的代码,以便在适当的点上处理对象,并且还去掉了async,因为您处理的是纯同步操作:

public static string Encode()
{
    var payload = Encoding.ASCII.GetBytes("some text");
    using (var outputStream = new MemoryStream())
    {
        using (var compressionStream = new GZipStream(outputStream, CompressionMode.Compress))
        {
            compressionStream.Write(payload);
        }
        var result = outputStream.ToArray();
        return Convert.ToBase64String(result);
    }   
}

这将产生输出

H4sIAAAAAAAAAyvOz01VKEmtKAEAur26TwkAAAA=

这比您看到的输出稍长,表明它包含Python所期望的页脚。不过,至少在.NET中,它仍然解码到相同的结果

有趣的是,.NET的GzipStream对缺少的页脚是健壮的,但是Python的版本不是

相关问题 更多 >