GZipStreamはgzip形式の圧縮・展開(伸張)を行うためのストリーム。 .NET FrameworkではHttpWebResponseクラスがgzipで圧縮されたコンテンツ(Content-Encoding: gzip)を展開する場合にGZipStreamを使用するが、ファイルの圧縮などにも利用することができる。
GZipStreamは圧縮と展開のどちらにも対応しているが、インスタンス生成時に圧縮用か展開用かどちらか一方を指定する必要がある。 このストリームに対して書き込み・読み込みを行うことにより、gzip形式での圧縮・展開することができる。
類似のクラスとして、LZ77形式の圧縮・展開を行うためのDeflateStreamというクラスもある。 gzip形式・LZ77形式のいずれも可逆圧縮なので、当然圧縮前と展開後のデータのサイズは同じになる。
主なコンストラクタ
- GZipStream(Stream, CompressionMode)
- 圧縮・展開を行う対象のストリーム、圧縮か展開のどちらの操作を行うか指定してインスタンスを生成する。 圧縮用にストリームを作成する場合はCompressionMode.Compress、展開用にストリームを作成する場合はCompressionMode.Decompressを指定する。
- GZipStream(Stream, CompressionMode, Boolean)
- 圧縮/展開が終わってCloseしたあともストリームを開いたままにするかどうかを指定してインスタンスを生成する。 Trueを指定すると、GZipStreamを閉じてもベースとなるストリームは開かれたままになるので、圧縮・展開したストリームを使って追加の処理を行えるようストリームを再利用することができる。
主なメソッド
- void Write(byte[], int, int)
- 指定したバイト配列を圧縮し、ストリームに書き込む。
- int Read(byte[], int, int)
- ストリームから展開したデータを読み込み、指定したバイト配列に書き込む。
主な呼び出し順序
圧縮する場合。
- new GZipStream()でCompressionMode.Compressを指定
- Write()
- Close()
展開する場合。
- new GZipStream()でCompressionMode.Decompressを指定
- Read()
- Close()
使用例
gzファイルの書き込み・読み込み
GZipStreamを使って圧縮済みのテキストファイル(.txt.gz
)を書き込み・読み込みする。 未圧縮の一時ファイル(.txt
)を生成せず、直接圧縮済みのファイル(.txt.gz
)を読み書きする。 FileStreamクラスをGZipStreamクラスでラップすることにより、圧縮・展開を行った上でファイル内容の読み書きを行うことができる。
gzip展開してファイル内容を表示するzcat
コマンドを用いて上記のコードが生成するsample.txt.gz
の内容を表示すると次のようになる。
この例のようにストリームを多段に重ねて使う方法についての詳細はストリームの基本とStreamクラス §.データフォーマットの変換やバッファリングなどの機能を追加するStream派生クラスを参照のこと。
ファイルの圧縮・展開
GZipStreamを使ってテキストファイルの内容を圧縮して別のファイルに保存する。 また、圧縮したファイルを再び展開して別のファイルに保存する。 この例で使用しているStream.CopyToメソッドは.NET Framework 4以降でないと使用できないので注意。
同じ内容のファイルについて、GZipStreamの代わりにDeflateStreamを使用して実行した例。
ZIPアーカイブを作成したい場合は、System.IO.Compression.ZipArchiveクラスを用いることができる。
圧縮レベルの指定
.NET Framework 4.5からは、GZipStream・DeflateStreamのコンストラクタにCompressionLevel列挙体の値を指定できるようになっている。 これにより圧縮時の圧縮レベルを指定することができる。 GZipStream・DeflateStreamに指定できる圧縮レベルは次のとおり。
CompressionLevel | 圧縮レベル |
---|---|
CompressionLevel.Optimal | 圧縮率優先 |
CompressionLevel.Fastest | 圧縮速度優先 |
CompressionLevel.NoCompression | 無圧縮 |
GZipStreamにCompressionLevelを指定して圧縮した場合の所要時間、圧縮率の違いは次の通り。