System.IO.Compression.GZipStream或System.IO.Ccompression.Deflate是否与zlib压缩兼容?
来自MSDN关于System.IO.Compression.GZipStream:
此类表示gzip数据格式,该格式使用行业标准算法进行无损文件压缩和解压缩。
另一方面,zlib中的gz*函数使用gzip格式。
因此,zlib和GZipStream应该是可互操作的,但前提是您使用zlib函数来处理gzip格式。
据报道,System.IO.Compression.Deflate和zlib不可互操作。
如果您需要处理zip文件(您可能不需要,但其他人可能需要),则需要使用SharpZipLib或其他第三方库。
我在Git对象方面遇到了这个问题。在这种特殊情况下,它们将对象存储为带有Zlib头的收缩Blob,这在RFC 1950。您可以通过创建一个包含以下内容的文件来创建兼容的blob:
- Two header bytes (CMF and FLG from RFC 1950) with the values
0x78 0x01
CM
= 8 = deflateCINFO
= 7 = 32Kb windowFCHECK
= 1 = checksum bits for this header
- The output of the C#
DeflateStream
- An Adler32 checksum of the input data to the
DeflateStream
, big-endian format (MSB first)
我自己做了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;
}
}
}
差不多就是这样。
DotNetZip包括一个DeflateStream、一个ZlibStream和一个GZipStream,用于处理RFC 1950、1951和1952。所有这些都使用DEFLATE算法,但每一个帧和头字节都不同。
作为一个优势,DotNetZip中的流不会显示针对内置流报告的压缩下扩展数据大小的异常。此外,没有内置的ZlibStream,而DotNetZip为您提供了这一点,以便与zlib进行良好的互操作。
我已经使用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);
}
在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相比,它提供了更好的压缩算法,在大多数情况下,还提供了更小的压缩文件。
我同意安德里亚斯的观点。你可能无法在外部工具中打开文件,但如果该工具需要流,你可能可以使用它。你也可以使用相同的压缩类将文件压缩回来。
- winforms
- combobox
- fogbugz
- java
- date
- internationalization
- asp.net
- iis
- url-rewriting
- urlrewriter
- c#
- enums
- ocaml
- haxe
- algorithm
- string
- viewstate
- .net
- c++
- c
- symbol-table
- mysql
- database
- postgresql
- licensing
- migration
- vb.net
- vb6
- declaration
- vb6-migration
- python
- psycopg2
- backup
- vmware
- virtualization
- gnu-screen
- authentication
- desktop
- excel
- xll
- cultureinfo
- regioninfo
- oracle
- client
- session
- download
- html
- virtual
- constructor
- scenarios
- perl
- full-text-search
- javascript
- ajax
- testing
- oop
- inheritance
- vim
- encapsulation
- information-hiding