4

1990 年代に Jean-loup Gailly によって書かれた ZLIB ライブラリを使用して圧縮されたデータを解凍しようとしています。これは人気のあるライブラリだと思います (使用する zlib32.dll ファイルを出荷する多くのプログラムを目にします)。私が読んだものから rfc-1951 DEFLATE 形式を使用する compress() 関数を直接使用しています。

これは、ストリームから圧縮データを読み取って解凍するために使用しているコードの一部です。

InputStream is = new ByteArrayInputStream(buf);

//GZIPInputStream gzis = new GZIPInputStream(is);

InflaterInputStream iis = new InflaterInputStream(is);

byte[] buf2 = new byte[uncompressedDataLength];

iis.read(buf2);

iis.read(buf2) 関数は、「データ形式エラー」の内部例外をスローします。GZIPInputStream も使用してみましたが、同じ例外がスローされます。

「buf」変数は byte[] 型であり、C プログラムが ZLIB compress() 関数から取得したものと同じであることをデバッグで確認しました (実際のデータは TCP 経由でサーバーから取得されます)。「uncompressedDataLength」は、C プログラム (サーバー) によっても提供された非圧縮データの既知のサイズです。

このライブラリを使用してデータの読み取り/書き込みを試みた後、Java を使用して Android で同じデータの読み取り/書き込みを試みた人はいますか?

いくつかの場所で参照されている「ZLIB の純粋な Java ポート」を見つけました。必要に応じてそれを試すこともできますが、可能であれば組み込み/OS 関数を使用したいと思います。

4

1 に答える 1

7

ここで使用されているデータ形式deflatezlib、およびgzipはすべて関連しています。

  • 基本は、RFC 1951で定義されているdeflate圧縮データ形式です。純粋な形では役に立たないことが多いため、通常はラッピング形式を使用します。

  • gzip圧縮データ形式 ( RFC 1952 ) は、ファイルの圧縮を目的としています。これは、ファイル名といくつかの属性用のスペースを持つヘッダー、デフレート データ ストリーム、末尾の CRC-32 チェックサム (4 バイト) で構成されます。(仕様では、1 つのストリームで複数のそのようなファイルをサポートすることもできますが、これはあまり使用されていないと思います。)

  • RFC 1950で定義されたzlib圧縮データ形式: 小さいヘッダー (2 または 6 バイト)、デフレート データ ストリーム、および末尾の Adler-32 チェックサム (4 バイト) で構成されます。(Adler-32 チェックサムは、gzip で使用される CRC-32 チェックサムよりも高速に計算することを目的としています。) 他のプロトコル内でのデータの圧縮送信、または他のファイル形式内での圧縮ストレージを目的としています。たとえば、PNG ファイル形式内で使用されます。

zlib ライブラリは、これらすべての形式をサポートしています。Java の java.util.zip は (VM の実装/ネイティブ呼び出しの一部として) zlib に基づいて構築されており、いくつかのクラスでこれらへのアクセスを公開します。

  • Deflater クラスと Inflater クラスnowrapは、コンストラクターへの引数に応じて、zlibまたはdeflateデータ形式を実装します。

  • DeflaterOutputStream/DeflaterInputStream/InflaterInputStream/InflaterOutputStream は、Deflater/Inflater 上に構築されます。ドキュメントには、デフォルトの Inflater/Deflater がzlibを実装するかdeflateを実装するかが明確に記載されていませんが、ソースはzlibDeflaterを実装するデフォルトまたはInflaterコンストラクタを使用することを示しています。

  • GZipOutputStream/GZipInputStream は、名前が示すように、gzip形式を実装します。

compresszlib の関数のソース コードを見てみたところ、このzlib形式を使用しているようです。したがって、コードは正しいことを行う必要があります。欠落したデータや、圧縮データ ブロックの一部ではない追加データが前後にないことを確認してください。

免責事項:これは Java SE の状態です。Android の場合も同様だと思いますが、これを保証することはできません。

あなたが見つけた(おそらく)jzlibライブラリは、zlibのJava再実装であり、これらすべてのデータ形式も実装しています(最新の更新でgzipが追加されました)(圧縮側で) インタラクティブに使用する場合は、java.util のクラスでは不可能ないくつかのフラッシュ アクション (圧縮レベルの変更などのいくつかの回避策を使用する以外) が可能になるため、望ましいです。ネイティブ呼び出し (常にいくらかのオーバーヘッドがあります)。

PS: zip (または pkzip) ファイル形式も関連しています。アーカイブ内の各ファイルに対して内部的に deflate を使用します。

于 2011-11-12T17:14:30.710 に答える