システム学習Java IO(二)----IO異常処理
2901 ワード
ディレクトリ:システム学習Java IO----ディレクトリ、概要
ストリームを使用すると、StreamsとReaders/Writersを正しく閉じる必要があります.これはclose()メソッドを呼び出すことによって行われます.次のコードを見てください.
このコードは一見問題ないようです.しかしdoSomethingWithData()メソッドの内部から異常が放出されるとどうなりますか?そうだ!
しかしclose()メソッド自体が異常を投げ出すとどうなるのでしょうか.このように流れは閉鎖されますか?このような状況をキャプチャするには、try-catchブロックにclose()の呼び出しを以下に示すように含める必要があります.
これは確かに問題を解決することができますが、うるさいので見苦しいです.この問題を解決する方法がある.これらの重複コードを抽出して「例外処理テンプレート」と呼ばれる方法を定義します.例外処理テンプレートを作成し、使用後にストリームを正しく閉じます.このテンプレートは一度だけ作成し、コード全体で繰り返し使用しますが、面倒な感じがして、展開しません.
Java 7からtry-with-resourcesという構造を使うことができます
tryブロックが完了すると、FileInputStreamは自動的に閉じられます.言い換えれば、スレッドがtryコードブロックを実行している限り、inputstreamは閉じられます.FileInputStreamがJavaインタフェースjavaを実現したからです.lang.AutoCloseable、このインタフェースを実装するすべてのクラスはtry-with-resources構造で使用できます.
FileInputStreamはこのclose()メソッドを書き換え、ソースコードを表示すると、その下位層がnativeメソッドを呼び出して動作していることがわかります.
try-with-resources構造はJavaの組み込みクラスにのみ適用されません.独自のクラスでjavaを実現することもできる.lang.AutoCloseableインタフェースは、try-with-resources構造などとともに使用されます.
try-with-resourcesは、try-catchブロックで使用されるリソースが自分で作成したものであっても、Javaの組み込みコンポーネントであっても、正しく閉じられるようにする強力な方法です.
ストリームを使用すると、StreamsとReaders/Writersを正しく閉じる必要があります.これはclose()メソッドを呼び出すことによって行われます.次のコードを見てください.
InputStream input = new FileInputStream("D:\\out.txt");
int data = input.read();
while(data != -1) {
//do something with data...
doSomethingWithData(data);
data = input.read();
}
input.close();
このコードは一見問題ないようです.しかしdoSomethingWithData()メソッドの内部から異常が放出されるとどうなりますか?そうだ!
input.close();
は実行の機会が得られず、InputStreamは永遠に閉じません!このような状況を回避するために、ストリームを閉じるコードをfinallyブロックに入れて必ず実行されることを確保し、コードを次のように書き換えることができます.InputStream input = null;
try{
input = new FileInputStream("D:\\out.txt");
int data = input.read();
while(data != -1) {
//do something with data...
doSomethingWithData(data);
data = input.read();
}
}catch(IOException e){
//do something with e... log
} finally {
if(input != null) input.close();
}
しかしclose()メソッド自体が異常を投げ出すとどうなるのでしょうか.このように流れは閉鎖されますか?このような状況をキャプチャするには、try-catchブロックにclose()の呼び出しを以下に示すように含める必要があります.
} finally {
try{
if(input != null) input.close();
} catch(IOException e){
//do something, or ignore.
}
}
これは確かに問題を解決することができますが、うるさいので見苦しいです.この問題を解決する方法がある.これらの重複コードを抽出して「例外処理テンプレート」と呼ばれる方法を定義します.例外処理テンプレートを作成し、使用後にストリームを正しく閉じます.このテンプレートは一度だけ作成し、コード全体で繰り返し使用しますが、面倒な感じがして、展開しません.
Java 7からtry-with-resourcesという構造を使うことができます
// try
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
} }
tryブロックが完了すると、FileInputStreamは自動的に閉じられます.言い換えれば、スレッドがtryコードブロックを実行している限り、inputstreamは閉じられます.FileInputStreamがJavaインタフェースjavaを実現したからです.lang.AutoCloseable、このインタフェースを実装するすべてのクラスはtry-with-resources構造で使用できます.
public interface AutoCloseable {
void close() throws Exception;
}
FileInputStreamはこのclose()メソッドを書き換え、ソースコードを表示すると、その下位層がnativeメソッドを呼び出して動作していることがわかります.
try-with-resources構造はJavaの組み込みクラスにのみ適用されません.独自のクラスでjavaを実現することもできる.lang.AutoCloseableインタフェースは、try-with-resources構造などとともに使用されます.
public class MyAutoClosable implements AutoCloseable {
public void doIt() {
System.out.println("MyAutoClosable doing it!");
}
@Override
public void close() throws Exception {
System.out.println("MyAutoClosable closed!");
} }
private static void myAutoClosable() throws Exception {
try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
myAutoClosable.doIt();
}
}
// :
// MyAutoClosable doing it!
// MyAutoClosable closed!
try-with-resourcesは、try-catchブロックで使用されるリソースが自分で作成したものであっても、Javaの組み込みコンポーネントであっても、正しく閉じられるようにする強力な方法です.