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





Они просто сжимают данные с помощью алгоритмов 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 или другую стороннюю библиотеку.
re: "по сообщениям, не совместим" в отношении zlib и DeflateStream. Они ДЕЙСТВИТЕЛЬНО несовместимы. Есть три IETF RFC, охватывающих это пространство: 1950 для ZLIB, 1951 для DEFLATE и 1952 для GZIP. Deflate - это алгоритм сжатия. ZLIB и GZIP - это разные форматы, которые определяют метаданные, также известные как «заголовки», которые применяются к сжатому потоку. Библиотека zlib реализует как ZLIB, так и GZIP. Чтобы было интересно, и ZLIB, и GZIP могут использовать DEFLATE в качестве механизма сжатия. Класс DeflateStream создает чистый поток без заголовков. Неудивительно, что мы все запутались.
Я использовал 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», он становится совершенно правильным архивным файлом. Вы даже можете изменить его содержимое с помощью любого инструмента архивирования, и оно останется десериализованным с использованием вашего метода.
DotNetZip включает DeflateStream, ZlibStream и GZipStream для обработки RFC 1950, 1951 и 1952. Все они используют алгоритм DEFLATE, но байты кадрирования и заголовка различны для каждого из них.
В качестве преимущества потоки в DotNetZip не демонстрируют аномалия увеличения размера данных при сжатии, сообщаемое по сравнению со встроенными потоками. Кроме того, нет встроенного ZlibStream, тогда как DotNetZip дает вам это для хорошего взаимодействия с zlib.
Я столкнулся с этой проблемой с объектами Git. В этом конкретном случае они хранят объекты как спущенные капли с заголовком Zlib, который задокументирован в RFC 1950. Вы можете создать совместимый большой двоичный объект, создав файл, содержащий:
0x78 0x01CM = 8 = спуститьCINFO = 7 = окно 32 КБFCHECK = 1 = биты контрольной суммы для этого заголовкаDeflateStreamDeflateStream с прямым порядком байтов (сначала 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
Начиная с .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.
zip-файлы - это не то же самое, что файлы, сжатые zlib (алгоритмы сжатия могут быть такими же, но заголовки - нет)