GZipStream bug?
.NET2.0(β1)からHTTP1.1でサポート可能なGZip圧縮/圧縮解除を可能としたストリームクラスであるGZipStreamがやっとこ標準で実装された。
私の所のようにJava側とHTTP通信を行うようなシステムではGZip圧縮によるネットワークの帯域削減は効果の有無は計測で判断するとしても必ず実装が必要なのだ。
しかし.NET側でGZip圧縮済みのデータを圧縮解除するこんなメソッドを作って実行すると
public void DeCompress(Stream stream) { using (GZipStream compressedzipStream = new GZipStream(stream, CompressionMode.Decompress)) { MemoryStream ms = new MemoryStream(); while (true) { int b = compressedzipStream.ReadByte(); if (b == -1) break; ms.WriteByte((byte)b); } }; }
引数のストリームで取得できるバイト長がある一定よりも短いとなぜか例外が発生する。
Message: The CRC in GZip footer does not match the CRC calculated from the decompressed data. Source: System 場所 System.IO.Compression.Inflater.Inflate(Byte bytes, Int32 offset, Int32 length) 場所 System.IO.Compression.DeflateStream.Read(Byte array, Int32 offset, Int32 count) 場所 System.IO.Compression.GZipStream.Read(Byte[] array, Int32 offset, Int32 count) 場所 System.IO.Stream.ReadByte()
他のオープンソースのGZipStream実装(※)で試した所上手く行くので今回はどう考えても.NETのバグっぽい。
それにしてもGZip等の特定の圧縮ロジックを持つライブラリィのデバッグ、それもプラットホームが異なる場合は苦労が増える事を実感した。
Java側と.NET側のどちらの実装がおかしいのかをはっきりさせなくちゃならないから互いの実装の細かい所まで調べてるうちに結局はGZipそのもののフォーマットを詳しく調べるはめになっちゃった。これはこれで勉強になるからいいんだけど...でも..... 確か別なRFCでも同じような作業をしたような気がするのだ(RFCデジャヴュと言う)
※のGZipInputStreamクラスを試用