Zlib-совместимые потоки сжатия?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
13
0
21 179
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

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

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

Ответ принят как подходящий

Из MSDN о System.IO.Compression.GZipStream:

This class represents the gzip data format, which uses an industry standard algorithm for lossless file compression and decompression.

С zlib FAQ:

The gz* functions in zlib on the other hand use the gzip format.

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

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

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

zip-файлы - это не то же самое, что файлы, сжатые zlib (алгоритмы сжатия могут быть такими же, но заголовки - нет)

Ben Collins 09.10.2008 19:26

re: "по сообщениям, не совместим" в отношении zlib и DeflateStream. Они ДЕЙСТВИТЕЛЬНО несовместимы. Есть три IETF RFC, охватывающих это пространство: 1950 для ZLIB, 1951 для DEFLATE и 1952 для GZIP. Deflate - это алгоритм сжатия. ZLIB и GZIP - это разные форматы, которые определяют метаданные, также известные как «заголовки», которые применяются к сжатому потоку. Библиотека zlib реализует как ZLIB, так и GZIP. Чтобы было интересно, и ZLIB, и GZIP могут использовать DEFLATE в качестве механизма сжатия. Класс DeflateStream создает чистый поток без заголовков. Неудивительно, что мы все запутались.

Cheeso 16.05.2009 18:06

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

работает как шарм! Большой набор данных, который я использую для тестирования производительности, был сжат с 55 МБ до 7,5 МБ без заметной потери производительности. P.S. Если «файл» переименован в «file.gz», он становится совершенно правильным архивным файлом. Вы даже можете изменить его содержимое с помощью любого инструмента архивирования, и оно останется десериализованным с использованием вашего метода.

Soonts 30.01.2010 18:46

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 с прямым порядком байтов (сначала MSB)

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

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;
        }
    }
}

Вот и все.

Спасибо, сэр! Это очень помогло. Я не делал это классом, просто поместил все это в функцию и сделал ее статической: P

VenoMpie 05.03.2021 09:45

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

Из класса Статья MSDN:

This class represents the Deflate algorithm, which is an industry-standard algorithm for lossless file compression and decompression. Starting with the .NET Framework 4.5, the DeflateStream class uses the zlib library. As a result, it provides a better compression algorithm and, in most cases, a smaller compressed file than it provides in earlier versions of the .NET Framework.

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