私は DeflateStream の内部に精通していませんが、バイナリ添付ファイルで DeflateStream を使用するベンダーの DB システムにファイルを保存する必要があります。私が最初に気付いたのは、すべてのファイルが圧縮後に 10 ~ 50% 大きくなったことですが、これは、高度に圧縮されたファイル (この場合はすべて PDF) に加えて、あまり洗練されていない圧縮アルゴリズムが原因であると考えています。ただし、私の質問は、元のファイルを BLOB に書き込んだときに、ベンダーのアプリケーションで問題なく開くことができたという事実に関連しています (deflate で圧縮した添付ファイルも開きました)。データが圧縮されていないことを DeflateStream に伝え、基本的にそのまま渡すヘッダーが圧縮データにありますか? これ仕様です。それに精通している人は、これが定義されている場所を指摘できますか?それとも、私がベースから外れていて、ベンダーが舞台裏で魔法をかけているのでしょうか?
3 に答える
いいえ、DeflateStreamにはそのような魔法はありません。
組み込みのdeflateStreamは、以前に圧縮されたデータのサイズが実際に大きくなる圧縮異常を示します。これは以前にMicrosoftに報告されていますが、問題の修正を拒否しました。これは、DEFLATEプロトコルのDeflateStreamでの単純な実装と関係があります。問題を回避するために私が知っている方法:
この問題を示さない代替のdeflateStreamを使用してください。一例として、DotNetZipを参照してください。これには、正常に機能するDeflateStreamが含まれています。
壊れたDeflateStreamを使用し、ストリームを圧縮し、サイズを比較します。「圧縮された」ストリームの方が大きい場合は、「非圧縮」ストリームの使用にフォールバックします。
前者の場合を選択した場合でも、すでに圧縮されているものを圧縮している状態になります。言い換えれば、不要な二重圧縮です。したがって、何を選択するかに関係なく、それを回避することを検討することをお勧めします。
ストリーム圧縮はファイル圧縮とは異なります。ファイルを圧縮する場合、通常、ファイル全体に対して複数のパスを作成し、1つにコミットする前に、使用する圧縮スキームを決定することができます。ストリームを圧縮する場合、圧縮ルーチンがどの圧縮方法が最適になるかを知るのに十分なデータを処理する前に、データの出力を開始する必要があることがよくあります。
この影響は、データをブロックに分割し、ブロックごとにデータの表現方法を決定し、各ブロックの先頭にデータの保存方法を識別するヘッダーを含めることで、ある程度軽減できます。残念ながら、余分なブロックヘッダーは、結果のストリームのサイズに追加されます。さらに、多くの圧縮スキームは、ストリームを処理するときに有効性が向上します。ファイル全体を圧縮するとかなりのスペースが節約される場合でも、ファイル内のすべての1kブロックが個別に「圧縮」されると拡張される可能性があります(たとえば、コンプレッサーが一般的なバイトシーケンスのディクショナリを構築できるため)。圧縮/解凍のペアを設計して、拡張するデータのブロックがコンプレッサーによって逐語的に書き出されるようにすることができます(ヘッダーバイトはそれが何であったかを示します)。そして、圧縮機が実行できたのと同じ方法でブロックする解凍プロセスを使用して、ブロックが「圧縮」形式で格納されていた場合に追加されたのと同じバイトシーケンスを辞書に追加します。このようなアプローチはおそらく良いアプローチですが、アンコンプレッサーの複雑さが大幅に増します。
ただし、DeflateStreamの最大の問題は、既存の「非圧縮」コードと互換性のない圧縮データを生成せずに、最悪の場合の「圧縮」パフォーマンスを改善する方法がない可能性があることです。バイトQの文字列があり、.net2.0に付属の「uncompress」コードにフィードすると同じシーケンスが生成されるバイトシーケンスが必要であるとします。Qのいくつかの可能な値については、Qよりもそれほど大きくない入力シーケンスがない可能性があります。その場合、Microsoftがタイムマシンなしで問題を「修正」する方法はありません。
それはすべて、DEFLATE ストリームがどのように作成されたかによって異なります。
DEFLATEは「非圧縮ブロック」 (BTYPE=00) をサポートし、このブロック内のすべてのデータは、使用する必要があり、圧縮なしで逐語的に保存されます。ブロック ヘッダー、長さ、生データのみです。ただし、ストリームは有効な DEFLATE ストリームであり、圧縮率が標準以下になる場合でも、「圧縮されていない」ブロックがゼロ (または十分でない) である可能性があります。
全体的な圧縮率は、データ、圧縮アルゴリズム/実装、および圧縮の実行にかかる労力によって異なります。
ハッピーコーディング。