我正在使用c# GZipStream类来压缩一些输入数据。问题是当输入为空时。在这种情况下,它最终会创建一个0字节的文件。当我尝试使用7zip解压缩生成的.gz文件时,它给出了一个错误,说格式无效。如果我有一个非空的输入,它工作得很好。请告诉我如何创建一个有效的。gz文件,将解压缩成一个0字节的文件?
var file = new FileStream("foo.txt.gz", FileMode.Create, FileAccess.ReadWrite);
var gzip = new GZipStream(file, CompressionMode.Compress);
var writer = new StreamWriter(gzip);
for (string line in input) {
writer.Write(line);
}
writer.Close();
gzip.Close();
file.Close();
在上面的代码中,如果我的'input'数组是空的,我最终写了一个0字节的文件foo.txt.gz, 7zip表示该文件无效。但如果我有一个非空数组,我得到一个有效的文件。请告诉我如何修改我的代码来解决这个问题,使我得到一个有效的.gz文件,即使输入是空的。谢谢!
编辑:这可能是。net中的一个bug。如果你注意到同样的问题,并同意这是一个bug,请投票:https://connect.microsoft.com/VisualStudio/feedback/details/888912/gzipstream-creates-invalid-gz-files-when-input-is-empty
不幸的是,这看起来像是。net库中GZipStream实现的一个bug。
根据文档,根据MSDN (http://msdn.microsoft.com/en-ca/library/as1ff51s.aspx),它应该"显示为一个有效的空压缩文件"。但是,当我测试你的代码和一些变化时,我也得到一个完全空的文件。
作为比较,如果我使用Cygwin (echo -n | gzip -9> empty.gz)创建一个空的gzip文件,我会得到一个20字节的文件。
我想您可以通过检测何时输入为空并手动写出空GZIP文件来解决这个问题。您可以参考GZIP文件文档(Wikipedia将是一个很好的起点)手动创建文件,或者硬编码程序中空文件所需的20字节(使用这种解决方案,内部时间戳和一些其他标志可能是错误的,但这可能不会影响您在实践中)。
或者,使用第三方压缩库,如SharpZipLib (http://icsharpcode.github.io/SharpZipLib/)或DotNetZip (http://dotnetzip.codeplex.com/),实现GZIP,并使用他们的实现,而不是GZipStream。
我知道这是一个老问题,但如果你意识到你的输入流是空的,在处置GZipStream类之前,你可以只做一个空写,它会按预期将20字节保存到输出流,创建一个有效的gz文件。
可以使用以下代码片段:
gs.Write(Array.Empty<byte>(), 0, 0);