如何在不解压缩的情况下创建Gzip文件?

时间:2017-03-26 02:59:11

标签: c# .net-3.5 gzip outputstream gzipstream

我使用以下方法通过压缩数据来创建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文件?如果是这样,我在这里做错了什么?如果没有,有没有其他方法来实现这一目标?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

尽管很可能,但我很确定它会使文件部分或完全无法读取,因为您附加的未压缩数据与gzip格式规范不匹配。 我还应该注意,GzipStream没有提供任何从存档中添加或提取文件的方法,你可能想要查看ZipArchive类。

答案 1 :(得分:1)

GZipStreamZIP文件格式不同 - 因此您无法将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