我使用以下方法通过压缩数据来创建Gzip文件。
public static void GZipCompress(Stream dataToCompress, Stream outputStream)
{
GZipStream gzipStream = new GZipStream(outputStream, CompressionMode.Compress);
int readBufferSize = 10000;
byte[] data_ = new byte[readBufferSize];
int bytesRead = dataToCompress.Read(data_, 0, readBufferSize);
while (bytesRead > 0)
{
gzipStream.Write(data_, 0, bytesRead);
data_ = new byte[readBufferSize];
bytesRead = dataToCompress.Read(data_, 0, readBufferSize);
}
try
{
gzipStream.Flush();
gzipStream.Close();
}
catch (ObjectDisposedException ioException)
{
}
}
但如果它已经是zip格式,我不应该压缩它。只需将数据附加到输出GZip文件而不进行压缩。我正在使用以下方法。
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[16 * 1024]; // Fairly arbitrary size
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
output.Flush();
output.Close();
}
当文件的扩展名不包含" zip"我正在调用GZipCompress方法。当文件的扩展名为" zip"我正在调用CopyStream方法。但是在通过CopyStream将内容复制到输出流到GZip文件之后,当我尝试解压缩此文件时,我得到了以下异常。
An unhandled exception of type 'System.IO.InvalidDataException' occurred in System.dll
The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
是否可以将未压缩的数据写入GZip文件?如果是这样,我在这里做错了什么?如果没有,有没有其他方法来实现这一目标?任何帮助将不胜感激。
答案 0 :(得分:1)
尽管很可能,但我很确定它会使文件部分或完全无法读取,因为您附加的未压缩数据与gzip格式规范不匹配。 我还应该注意,GzipStream没有提供任何从存档中添加或提取文件的方法,你可能想要查看ZipArchive类。
答案 1 :(得分:1)
GZipStream
和ZIP
文件格式不同 - 因此您无法将ZIP用作GZipStream
的内容。
ZIP是多个可能压缩文件的容器,而GZipStream
是单个文件的压缩内容,没有任何其他标头。因此,当您尝试使用GZipStream
读取ZIP的内容时,它将找到ZIP的容器标头而不是预期的GZip签名 - 因此无法解析。
如果您想将多个文件打包成一个 - 使用ZIP格式 - 请参阅Create normal zip file programmatically。如果您可以从3.5迁移到更新版本的.Net,则可以使用内置的ZipFile
和相关类而不是外部库。它还支持添加非压缩文件 - ZipArchive.CreateEntry(..., CompressionLevel.NoCompression)
。
如果您可以移动到4.5版本的框架GZipStream
支持压缩级别 - 那么您可以在不压缩的情况下编写.GZ文件 - GZipStream。