Вопрос

Совместимы ли System.IO.Compression.GZipStream или System.IO.Compression.Deflate со сжатием zlib?

Это было полезно?

Решение

От MSDN о System.IO.Compression.GZipStream:

Этот класс представляет формат данных gzip, который использует стандартный отраслевой алгоритм сжатия и распаковки файлов без потерь.

Из самого часто задаваемые вопросы по zlib:

С другой стороны, функции gz * в zlib используют формат gzip.

Таким образом, zlib и GZipStream должны быть совместимы, но только если вы используете функции zlib для обработки формата gzip.

System.IO.Compression.Как сообщается, Deflate и zlib несовместимы.

Если вам нужно обрабатывать zip-файлы (вероятно, у вас их нет, но это может понадобиться кому-то другому), вам нужно использовать Острый зажим или другая сторонняя библиотека.

Другие советы

DotNetZip - файл включает DeflateStream, ZlibStream и GZipStream для обработки RFC 1950, 1951 и 1952.Все они используют алгоритм DEFLATE, но байты кадрирования и заголовка различны для каждого из них.

В качестве преимущества потоки в DotNetZip не демонстрируют аномалия увеличения размера данных находится в состоянии сжатия, сопоставляется со встроенными потоками.Кроме того, нет встроенного ZlibStream, тогда как DotNetZip предоставляет вам это для хорошего взаимодействия с zlib.

Я столкнулся с этой проблемой с объектами Git.В этом конкретном случае они сохраняют объекты в виде спущенных больших двоичных объектов с заголовком Zlib, который задокументирован в RFC 1950.Вы можете создать совместимый большой двоичный объект, создав файл, содержащий:

  • Два байта заголовка (CMF и FLG из RFC 1950) со значениями 0x78 0x01
    • CM = 8 = сдуть
    • CINFO Окно = 7 = 32 КБ
    • FCHECK = 1 = биты контрольной суммы для этого заголовка .
  • Результат работы C# DeflateStream
  • Контрольная сумма Adler32 входных данных для DeflateStream, формат big-endian (сначала MSB)

Я создал свою собственную реализацию Adler

public class Adler32Computer
{
    private int a = 1;
    private int b = 0;

    public int Checksum
    {
        get
        {
            return ((b * 65536) + a);
        }
    }

    private static readonly int Modulus = 65521;

    public void Update(byte[] data, int offset, int length)
    {
        for (int counter = 0; counter < length; ++counter)
        {
            a = (a + (data[offset + counter])) % Modulus;
            b = (b + a) % Modulus;
        }
    }
}

И это было в значительной степени все.

Я использовал GZipStream для сжатия выходных данных из .NET XmlSerializer, и он отлично справился с распаковкой результата с помощью gunzip (в cygwin), winzip и другого GZipStream.

Для справки, вот что я сделал в коде:

FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
using (GZipStream gzStream = new GZipStream(fs, CompressionMode.Compress))
{
  XmlSerializer serializer = new XmlSerializer(typeof(MyDataType));
  serializer.Serialize(gzStream, myData);
}

Затем, чтобы распаковать в c#

FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
using (Stream input = new GZipStream(fs, CompressionMode.Decompress))
{
   XmlSerializer serializer = new XmlSerializer(typeof(MyDataType));
   myData = (MyDataType) serializer.Deserialize(input);
}

Использование утилиты "file" в cygwin показывает, что действительно существует разница между одним и тем же файлом, сжатым с помощью GZipStream и GNU GZip (вероятно, информация заголовка, как указывали другие в этой теме).Однако это различие, по-видимому, не имеет значения на практике.

gzip - это deflate + некоторые данные верхнего и нижнего колонтитулов, такие как контрольная сумма, длина и т.д.Таким образом, они несовместимы в том смысле, что один метод может использовать поток из другого, но они используют один и тот же алгоритм сжатия.

Они просто сжимают данные с помощью алгоритмов zlib или deflate , но не предоставляют выходные данные для какого-то определенного формата файла.Это означает, что если вы сохраните поток как есть на жестком диске, скорее всего, вы не сможете открыть его с помощью какого-либо приложения (gzip или winrar), потому что заголовки файлов (магическое число и т.д.) Не включены в поток, и вы должны записать их самостоятельно.

Начиная с .NET Framework 4.5, System.IO.Compression.DeflateStream класс использует библиотеку zlib.

Из истории класса Статья в MSDN:

Этот класс представляет алгоритм Deflate, который является стандартным в отрасли алгоритмом сжатия и распаковки файлов без потерь.Начиная с .NET Framework 4.5, класс DeflateStream использует библиотеку zlib.В результате он обеспечивает лучший алгоритм сжатия и, в большинстве случаев, сжатый файл меньшего размера, чем в более ранних версиях .NET Framework.

Я согласен с Андреасом.Вероятно, вы не сможете открыть файл с помощью внешнего инструмента, но если этот инструмент ожидает поток, вы, возможно, сможете его использовать.Вы также сможете выкачать файл обратно, используя тот же класс сжатия.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top