Zlib-совместимые потоки сжатия? - PullRequest
13 голосов
/ 16 сентября 2008

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

Ответы [ 8 ]

14 голосов
/ 06 марта 2009

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

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

13 голосов
/ 25 февраля 2010

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

  • Два байта заголовка (CMF и FLG из RFC 1950) со значениями 0x78 0x01
    • CM = 8 = сдуть
    • CINFO = 7 = 32 КБ, окно
    • FCHECK = 1 = биты контрольной суммы для этого заголовка
  • Выход C # DeflateStream
  • Контрольная сумма Adler32 входных данных в формате DeflateStream с прямым порядком байтов (сначала 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;
        }
    }
}

И это было довольно много.

9 голосов
/ 16 сентября 2008

С MSDN о System.IO.Compression.GZipStream:

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

Из zlib FAQ :

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

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

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

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

6 голосов
/ 16 сентября 2008

Я использовал 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 (возможно, информация заголовка, как другие указали в этой теме) Однако на практике это различие, по-видимому, не имеет значения.

3 голосов
/ 16 сентября 2008

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

2 голосов
/ 16 сентября 2008

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

1 голос
/ 29 апреля 2015

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

Из статьи MSDN класса :

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

0 голосов
/ 16 сентября 2008

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

...