GZip页脚再生

时间:2014-03-13 15:49:09

标签: .net gzip file-format

我有一个上传文件的系统,通过GZip运行它们并将它们存储在服务器上。代码中的错误导致在写入内容被刷新之前将流位置设置为0,从而在文件中覆盖GZip标头,覆盖标头。

我已经创建了一个程序,用于在缺少它的文件中插入标题,但是当页脚不再匹配时,我无法解压缩文件。

是否可以从此状态更正文件页脚?我假设我可以将10字节标题添加到原始文档中,校验和用于文件正文,页脚是文件总长度,所以我可以将计数器增加10。

所有帮助都表示赞赏,因为这些文件非常重要。

由于

更新:

根据Iain的建议,我尝试使用Deflate algorythm解压缩zip文件的正文。代码如下:

    private void DecompressStream(Stream input, Stream output)
    {
        using (var memStream = new MemoryStream())
        {
            //Copy everything but last 8 bytes
            CopyStream(input, memStream, 8);
            memStream.Position = 0;

            using (var deflate = new DeflateStream(memStream, CompressionMode.Decompress))
            {
                //Now try to decompress the stream
                deflate.CopyTo(output);
            }
        }
    }

    private void CopyStream(Stream input, Stream output, int dropBytes)
    {
        byte[] buffer = new byte[32768];
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            var lastMessagePart = (input.Position == input.Length);

            //Might go negative - to fix.
            if (lastMessagePart)
                read -= dropBytes;

            output.Write(buffer, 0, read);
        }
    }

deflate.CopyTo(输出)行有一个异常,它失败了:未知的块类型。流可能已损坏。

更新2:

好的!我修好了。丢失前10个字节实际上并没有改变流或页脚的内容。所以只需再次添加它就可以使它工作。我的内存流逻辑中有一个小错误,这意味着当我直接将其输入GZip解压缩时它不起作用,但当我将其输出到磁盘并重新读取时,它工作正常。

感谢所有帮助人员,你让我从不同角度看待它。

更新3:

好吧,我还没修好它。我有一个小文件的修复,但更大的文件似乎仍然导致问题。我将继续调查,也许我能够找到解决方案。

1 个答案:

答案 0 :(得分:2)

当然,只要您忽略CRC校验和长度检查,您应该能够在没有页脚的情况下解压缩。 IIRC,gzip页脚大小是未压缩大小mod (2^31)-1

我不确定您是否能够在不解压缩的情况下重建正确的页脚,因为您需要原始数据来进行CRC校验。您不应该将所有解压缩的数据保存在内存中。

在.Net中,您可以使用deflate流而不是gzip,然后您不需要可以重建的页眉或页脚。如果有任何数据损坏,您将无法知道。

Deflate Stream (MSDN)