我有一个上传文件的系统,通过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:
好吧,我还没修好它。我有一个小文件的修复,但更大的文件似乎仍然导致问题。我将继续调查,也许我能够找到解决方案。
答案 0 :(得分:2)
当然,只要您忽略CRC校验和长度检查,您应该能够在没有页脚的情况下解压缩。 IIRC,gzip页脚大小是未压缩大小mod (2^31)-1
我不确定您是否能够在不解压缩的情况下重建正确的页脚,因为您需要原始数据来进行CRC校验。您不应该将所有解压缩的数据保存在内存中。
在.Net中,您可以使用deflate
流而不是gzip
,然后您不需要可以重建的页眉或页脚。如果有任何数据损坏,您将无法知道。