Closer

提供: Kiruah's Page
移動: 案内検索

機能

kommons-lib Closerは、ストリームクローズ処理を容易にするための機能を提供します。

通常記述

通常、確実にストリームをクローズするためにストリーム系の変数をtryの外に出し、finally でcloseメソッドを呼び出すよう実装します。

InputStream is = null;
OutputStream os = null;

try {
	is = new ~;
	// isを利用
	os = new ~;
	// osを利用
} finally {
	if (is != null) {
		try {
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	if (os != null) {
		try {
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

これを毎回記述するのは大変です。Closerでは以下のように記述し、ストリームインスタンスを保持・管理します。

Closerによる記述

try {
	InputStream is = Closer.set(new ~); // キャスト不要
	OutputStream os = Closer.set(new ~); // キャスト不要
	// isを利用
	// osを利用
} finally {
	Closer.close();
}

これによってfinallyまでスコープを見せるためにストリームの変数を外に出す必要があった従来の記述を簡素化することができます。

Closerの階層記憶

複数のメソッドにまたがる処理など、ストリームの扱いが複雑なケースにおいては、ストリームのクローズ単位を細かく分割することができます。 具体的にはbegin()メソッドを利用します。

public void func1() {
    try {
        Closer.begin();
        InputStream is = Closer.set(new ~); // キャスト不要
         OutputStream os = Closer.set(new ~); // キャスト不要
         // isを利用
         // osを利用
    } finally {
        Closer.closeAll();
    }
}

public void func2() {
    try {
        Closer.begin();
        InputStream is = Closer.set(new ~); // キャスト不要
         OutputStream os = Closer.set(new ~); // キャスト不要
         // isを利用
         // osを利用
    } finally {
        Closer.close();
    }
}

普通にCloser.begin()がない場合、func2()の終了後、func1()のストリームまでクローズしてしまいます。 ですが、Closer.begin();はそれまでのストリーム管理と以降の管理レイヤーを分割するため、Closer.begin()~Closer.close()までが1つのレイヤーとなり別管理となります。 Closer.begin()は複数階層を構築可能です。よって、全階層を一度に解放するCloser.closeAll();が用意されています。

1階層しかないことがわかっている場合はCloser.begin()は不要です。また、kommons-lib内ではCloserは利用していないため、自身のアプリケーション内でのみbegin()の利用を判断することができます。