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

How to create a Gzip file without decompression?

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

虽然这很有可能,但我很确定它会使文件部分或完全不可读,因为您附加的未压缩数据将不符合 gzip 格式规范。 我还应该注意,GzipStream 不提供任何从存档中添加或提取文件的方法,您可能需要查看 ZipArchive class.

GZipStreamZIP 文件格式是不同的东西 - 所以你不能使用 ZIP 作为 GZipStream.

的内容

ZIP 是多个潜在压缩文件的容器,而 GZipStream 是单个文件的压缩内容,没有任何额外的 header。因此,当您使用 GZipStream 尝试读取 ZIP 的内容时,它将找到 ZIP 的容器 header 而不是预期的 GZip 签名 - 因此无法解析。

如果您想将多个文件打包成一个 - 使用 ZIP 格式 - 请参阅 Create normal zip file programmatically. If you could move to newer version of .Net from 3.5 you can use built in ZipFile and related classes instead of external libraries. It also supports adding non-compressed files - ZipArchive.CreateEntry(..., CompressionLevel.NoCompression)

如果你可以移动到 4.5 版本的框架 GZipStream 支持压缩级别 - 这样你就可以在不压缩的情况下编写 .GZ 文件 - GZipStream.