13

System.IO.Compression.GZipStreamまたはSystem.IO.Compression.Deflateはzlib圧縮と互換性がありますか?

4

8 に答える 8

17

Git オブジェクトでこの問題に遭遇しました。その特定のケースでは、 RFC 1950で文書化されている Zlib ヘッダーを使用して、収縮した blob としてオブジェクトを格納します。以下を含むファイルを作成することで、互換性のある BLOB を作成できます。

  • 値を持つ 2 つのヘッダー バイト (RFC 1950 の CMF および FLG)0x78 0x01
    • CM= 8 = 空気を抜く
    • CINFO= 7 = 32Kb ウィンドウ
    • FCHECK= 1 = このヘッダーのチェックサム ビット
  • C# の出力DeflateStream
  • DeflateStreamビッグエンディアン形式 (MSB ファースト)への入力データの Adler32 チェックサム

独自の 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;
        }
    }
}

そして、それはほとんどそれでした。

于 2010-02-25T01:46:52.613 に答える
15

DotNetZipには、RFC 1950、1951、および 1952 を処理するための DeflateStream、ZlibStream、および GZipStream が含まれています。これらはすべて DEFLATE アルゴリズムを使用しますが、フレーミングとヘッダー バイトはそれぞれ異なります。

利点として、DotNetZip のストリームは、ビルトイン ストリームに対して報告された、圧縮下でのデータ サイズの拡大の異常を示しません。また、組み込みの ZlibStream はありませんが、DotNetZip は zlib との良好な相互運用性のためにそれを提供します。

于 2009-03-06T16:10:58.407 に答える
10

System.IO.Compression.GZipStream に関するMSDNから:

このクラスは、業界標準のアルゴリズムを使用してロスレス ファイル圧縮および圧縮解除を行う gzip データ形式を表します。

zlib FAQから:

一方、zlib の gz* 関数は gzip 形式を使用します。

したがって、zlib と GZipStream は相互運用可能である必要がありますが、gzip 形式を処理するために zlib 関数を使用する場合に限られます。

System.IO.Compression.Deflate と zlib は相互運用性がないと報告されています。

zip ファイルを処理する必要がある場合 (おそらく必要ありませんが、他の誰かがこれを必要とする場合があります)、SharpZipLibまたは別のサードパーティ ライブラリを使用する必要があります。

于 2008-09-16T09:18:21.490 に答える
6

GZipStreamを使用して.NETXmlSerializerからの出力を圧縮しましたが、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で「file」ユーティリティを使用すると、GZipStreamとGNU GZipで圧縮された同じファイル(おそらく他の人がこのスレッドで述べているようにヘッダー情報)の間に実際に違いがあることがわかります。ただし、この違いは実際には問題ではないようです。

于 2008-09-16T14:20:42.917 に答える
3

gzip は deflate + チェックサムや長さなどの一部のヘッダー/フッター データです。そのため、一方のメソッドが他方のストリームを使用できるという意味では互換性がありませんが、同じ圧縮アルゴリズムを採用しています。

于 2008-09-16T08:34:48.693 に答える
2

zlibまたはdeflateアルゴリズムを使用してデータを圧縮するだけですが、特定のファイル形式の出力は提供しません。つまり、ストリームをそのままハードドライブに保存すると、ファイルヘッダー(マジックナンバーなど)がストリームに含まれていないため、アプリケーション(gzipまたはwinrar)を使用してストリームを開くことができない可能性があります。それらを自分で書いてください。

于 2008-09-16T08:28:49.877 に答える
1

.NET Framework 4.5 以降、System.IO.Compression.DeflateStreamクラスは zlib ライブラリを使用します。

クラスのMSDNの記事から:

このクラスは、ロスレス ファイル圧縮および圧縮解除の業界標準アルゴリズムである Deflate アルゴリズムを表します。.NET Framework 4.5 以降、DeflateStream クラスは zlib ライブラリを使用します。その結果、より優れた圧縮アルゴリズムが提供され、ほとんどの場合、以前のバージョンの .NET Framework よりも小さい圧縮ファイルが提供されます。

于 2015-04-29T07:14:18.923 に答える
0

私はアンドレアスに同意します。おそらく、外部ツールでファイルを開くことはできませんが、そのツールがストリームを想定している場合は、それを使用できる可能性があります。同じ圧縮クラスを使用して、ファイルを元に戻すこともできます。

于 2008-09-16T08:31:52.380 に答える