ストリームのバイト配列を圧縮しようとしています。 ExtendedStreamは、基本ストリーム(デフォルトではMemoryStream)とのインターフェイスを作ったクラスです。元のデータを取り出して圧縮し、元のデータのサイズと圧縮前のサイズとを比較すると、元のデータよりも小さいことがわかります。元のファイルは、GZip圧縮解除されたファイルよりも大きいです。
オリジナルの長さ:51695、圧縮された長さ:26014、解凍長さ:48685.
私が保管していたタイル(7バイト)。 System.IO.Compression名前空間で提供されているGZipクラスを使用して圧縮します。
public static ExtendedStream GZipDecompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream();
GZipStream decompressStream = new GZipStream(stream.BaseStream, CompressionMode.Decompress, true);
int b = -1;
while ((b = decompressStream.ReadByte()) != -1)
{
outStream.WriteByte((Byte)b);
}
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
public static ExtendedStream GZipCompress(ExtendedStream stream)
{
ExtendedStream outStream = new ExtendedStream(); // base stream is a memorystream
GZipStream compressStream = new GZipStream(outStream.BaseStream, CompressionMode.Compress, true);
compressStream.Write(stream.ToArray(), 0, (int)stream.Length);
compressStream.Flush();
outStream.Seek(0, SeekOrigin.Begin);
return outStream;
}
希望の情報です。
最初に、完了したらGZipStreamオブジェクトで.Disposeを呼び出す必要があります。また、書き込み時には、GZipStreamを破棄した後にoutStreamで.Flushを呼び出す必要があります。第3に、これが.NET4の場合は、入力ストリームの基本メンバーの.CopyToメソッドを使用して、入力から出力にデータをコピーします(ストリームが大きくなると拡大縮小しない.ToArrayを使用するのではなく)。 – Joe
いいえ、解凍または圧縮するときに "outStream"でflushを呼び出す必要はありません。データはすでにストリームに入っています。 FlushingはMemoryStreamのため何もしません(そして、FYI MemoryStreamは何もしないようにFlushをオーバーライドします)。私はCopyToメソッドを念頭に置いておくつもりですが、GCは私のためにすべてのものを修正するだけです(私が知っているような駄目なデザインですが、これは設計目標#1ではありません)。 –
@スーパ、いいえ。ジョーは正しい。あなたは**正式に圧縮ストリームを閉じたり/処分しなくてはなりません。それ以上のインバウンドがないことが分かっていない限り、フラッシュは空にできません。圧縮の制限。これは圧縮において絶対に重要です(私はそれを十分に強調したと思いますか?)。 Btw:これを行うには、個々のバイトをコピーすることは恐ろしい方法です。 –