Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net GZip页脚再生_.net_Gzip_File Format - Fatal编程技术网

.net GZip页脚再生

.net GZip页脚再生,.net,gzip,file-format,.net,Gzip,File Format,我有一个系统可以上传文档,通过GZip运行它们并将它们存储在服务器上。代码中的一个错误导致在刷新写入内容之前将流位置设置为0,从而覆盖了文件中的GZip头 我已经创建了一个程序,在缺少页眉的文件中插入页眉,但由于页脚不再匹配,我无法解压缩该文件 是否可以从此状态更正文件页脚?我假设我可以将10字节的页眉添加到原始文档中,校验和用于文件体,页脚是文件的总长度,因此我可以将计数器增加10 感谢所有帮助,因为这些文件非常重要 谢谢 更新: 按照Iain的建议,我尝试使用Deflate算法解压缩zip文

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

我已经创建了一个程序,在缺少页眉的文件中插入页眉,但由于页脚不再匹配,我无法解压缩该文件

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

感谢所有帮助,因为这些文件非常重要

谢谢

更新:

按照Iain的建议,我尝试使用Deflate算法解压缩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:


好吧,我还没修好。我已经对小文件进行了修复,但较大的文件似乎仍然会导致问题。我将继续调查,也许我能找到一个解决方案。

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

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

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


嗨,伊恩,谢谢你的快速回复。我正在将内容复制到内存流中,剥离最后8个字节,然后尝试缩减-但是我得到了以下错误:未知块类型。流可能已损坏。可能,但请记住,deflate流也没有gzip幻数。在传递到deflate流之前,必须跳过流的前10个字节。第一位应该是000001010中的一位;其他任何东西都意味着损坏。我需要在文件顶部添加幻数才能运行DeflateStream吗?所有可以解压的现有文件(通过GZip)都以{31139,8,0,0,0,0,0,0,4,0}开头。我的所有损坏文件都没有这个。不,你不需要有标题。gzip是
页眉
+
放气
+
页脚
。如果缺少头文件,并且文件仍然无法压缩,那么它可能会丢失。你能在你的问题中发布一个坏文件的前几十个字节吗?你怎么知道你只重写了gzip头?您不应该修改gzip预告片。此处的长度不是gzip文件的长度,而是未压缩数据的长度。请提供覆盖gzip文件示例的前100个字节(十六进制)。