GZipStreamなど他のストリームのラッパーとして動作するストリームの場合、そのストリームを閉じる際にベースとなったストリームも一緒に閉じるかどうかを指定することができるものがあります。 コンストラクタの引数leaveOpenにtrueを指定すると、Closeメソッドを呼び出したりusingステートメントから抜けてストリームを閉じた場合でも、ベースとなったストリームは開いたままになります。
次の例では、GZipStreamを使ってメモリ上で圧縮・展開を行なっていますが、圧縮と展開で同じMemoryStreamを使えるようleaveOpenにtrueを指定してGZipStreamを作成しています。
ラッパーとなるストリームを閉じる際にベースとなったストリームを開いたままにする
using System;
using System.IO;
using System.IO.Compression;
class Sample {
static void Main()
{
// GZipStreamで圧縮した結果を書き込むためのMemoryStreamを作成する
using (var compressedStream = new MemoryStream()) {
// データを圧縮してcompressedStreamに書き込むためのGZipStreamを作成する
// (GZipStreamを閉じてもcompressedStreamは閉じないようleaveOpenをtrueにする)
using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Compress, true)) {
// 圧縮するファイルのFileStreamを作成する
using (var inputStream = File.OpenRead("sample.txt")) {
// inputStreamからデータを読み出し、gzipStreamに書き込む
inputStream.CopyTo(gzipStream);
}
}
// この時点でgzipStreamは閉じられるが、compressedStreamは引き続き使用できる
// compressedStreamの現在位置をストリームの先頭に戻し、GZipStreamで再度展開する
compressedStream.Position = 0L;
using (var gzipStream = new GZipStream(compressedStream, CompressionMode.Decompress, false)) {
// StreamReaderを使って展開した内容を読み込んで表示する
var reader = new StreamReader(gzipStream);
Console.WriteLine(reader.ReadToEnd());
}
// この時点でgzipStreamは閉じられるが、leaveOpenにfalseを指定しているため、
// compressedStreamも閉じられる
}
}
}
なお、StreamReader・StreamWriterやBinaryReader・BinaryWriterでもベースとなったストリームを開いたままにするかどうかを指定することができます。