【问题标题】:How to create a Gzip file without decompression?如何在不解压的情况下创建 Gzip 文件?
【发布时间】:2017-08-18 20:48:22
【问题描述】:

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

【问题讨论】:

  • 您可能正在使用 Stream 类的 Write 方法。确保将两个 GZipStream 传递给 CopyStream 方法,或者更好地将参数类型更改为 GZipStream 并执行此操作。
  • 即使我通过了GZipStreams,我仍然无法调用GzipStream的write方法。因为那会压缩数据吗?我不希望再次压缩已经压缩的数据:(
  • 不是文档。使用 GZipStreams 写入方法写入已压缩的数据。不确定这是否是您需要的。
  • 请进一步阅读,我上面的评论似乎是错误的,数据似乎确实被该方法压缩了。对不起。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 2011-07-20
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多