【问题标题】:Why does my GZip implementation result in invalid gzip为什么我的 GZip 实现会导致 gzip 无效
【发布时间】:2021-08-10 01:21:58
【问题描述】:

我正在尝试对一些数据进行 gzip 压缩,这些数据将由单独的应用程序(一个名为 Tiled 的 tilemap 程序)使用。我无法生成应用程序可以理解的数据,我相信这是因为我的压缩数据无效。为了验证,我在https://codebeautify.org/gzip-decompress-online 上测试了我的压缩base64 字符串,根据这个站点,我的gzip 字符串也是无效的。

我的实现是:

uint[] values = new uint[4];
values[0] = 1;
values[1] = 1;
values[2] = 1;
values[3] = 1;

using var memoryStream = new MemoryStream();
using var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress);
using var writer = new BinaryWriter(gzipStream);
for (int i = 0; i < values.Length; i++)
{
    writer.Write(values[i]);
}

writer.Flush();
gzipStream.Flush();
memoryStream.Position = 0;
var memoryBytes = memoryStream.ToArray();

var convertedString = Convert.ToBase64String(memoryBytes);

我的结果字符串是:

H4sIAAAAAAAACmJkYGBgRMIAAAAA//8=

在上面列出的 GZip 网站中输入时,它会返回“数据完整性错误”

但是,如果我尝试在 C# 中解压缩它,我会得到相同的数据,因此“往返”有效。

作为参考,通过 Tiled 压缩的相同数据 (1, 1, 1, 1) 会生成以下字符串:

H4sIAAAAAAAACmNkYGBgRMIAUPFgrRAAAAA=

这个字符串也可以在上面列出的网站中正确解压缩。请注意,这两个字符串都使用 C# 中的 GZipStream 正确解压缩,因此 .NET 中的 GZip 实现必须以某种方式更能容忍我做错的任何事情。

谁能告诉我为什么我的输出字符串与 Tiled 生成的字符串不匹配,为什么我的字符串根据 Tiled 和那个应用程序无效,以及如何解决这个问题?

【问题讨论】:

    标签: c# gzip gzipstream


    【解决方案1】:

    正如 Mark 所说,您需要使用 Close() 来完成 gzip 流。此外,您不需要刷新 writer 或重置 memoryStream 位置。这将通过关闭 GzipStream 实例来处理。

    uint[] values = new uint[4];
    values[0] = 1;
    values[1] = 1;
    values[2] = 1;
    values[3] = 1;
    
    using var memoryStream = new MemoryStream();
    using var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress);
    using var writer = new BinaryWriter(gzipStream);
    for (int i = 0; i < values.Length; i++)
    {
        writer.Write(values[i]);
    }
    
    gzipStream.Close();
    
    var memoryBytes = memoryStream.ToArray();
    var convertedString = Convert.ToBase64String(memoryBytes);
    

    【讨论】:

      【解决方案2】:

      Flush() 强制压缩到目前为止提供的数据,但不会完成 gzip 流。您需要使用Close()

      第一个是不完整的 gzip 流,在 deflate 流的中间结束并且没有 gzip 预告片。第二个是完整的 gzip 流,带有一个终止的 deflate 流,然后是一个带有 CRC 和长度的 gzip 预告片,用于检查未压缩的数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 1970-01-01
        相关资源
        最近更新 更多