3

IO を管理したときに、問題が見つかりました。私はこのようにそれを閉じていました:

try {
        // my code
    } catch (Exception e) {
        // my code
    } finally{
        if (is != null) {
            is.close();
        }
    }

しかし、close メソッドも例外をスローします。複数の IO がある場合は、すべてを閉じる必要があります。したがって、コードは次のようになります。

try {
    // my code
} catch (Exception e) {
    // my code
} finally{
    if (is1 != null) {
        is1.close();
    }
    if(is2 != null{
        is2.close();
    }
    // many IOs
}

is1.close() が例外をスローした場合、is2、is3 はそれ自体を閉じません。したがって、それらを制御するには、多くの try-catch-finally を入力する必要があります。問題を解決する他の方法はありますか?

4

2 に答える 2

3

車輪を再発明するのではなく、closeQuietly(...)Apache IOUtilsのメソッドを使用できます。これらのメソッドは、 から発生するものをすべてIOException押しつぶしclose()、引数が であるケースも処理しますnull

注意すべき唯一のことは、フラッシュされていないデータを含む出力ストリームでそれを呼び出さないことです。そうしてフラッシュが失敗した場合、それについては聞こえません。書き込んでいるデータが重要な場合、フラッシュが失敗したことを知らないのは悪いことです。

于 2012-11-05T05:04:16.683 に答える
1

私はこの小さな静的ユーティリティクラスを使用します。原則として、処理を誤って(何か)冗長に実行する必要がある場合、または最終的にブロックする場合は、アプリケーションコードを散らかすのではなく、少なくとも1回はリッピングして実装します。手元のタスクから気を散らすもの:

package krc.utilz.io;

import java.io.Closeable;
import krc.utilz.reflectionz.Invoker;

public abstract class Clozer
{
  /**
   * close these "streams"
   * @param Closeable... "streams" to close.
   */
  public static void close(Closeable... streams) {
    Exception x = null;
    for(Closeable stream : streams) {
      if(stream==null) continue;
      try {
        stream.close();
      } catch (Exception e) {
        if(x!=null)x.printStackTrace();
        x = e;
      }
    }
    if(x!=null) throw new RuntimeIOException(x.getMessage(), x);
  }

  /**
   * Close all the given objects, regardless of any errors.
   * <ul>
   * <li>If a given object exposes a close method then it will be called. 
   * <li>If a given object does NOT expose a close method then a warning is 
   *   printed to stderr, and that object is otherwise ignored.
   * <li>If any invocation of object.close() throws an IOException then
   *     <ul>
   *     <li>we immediately printStackTrace
   *     <li>we continue to close all given objects
   *     <li>then at the end we throw an unchecked RuntimeIOException
   *     </ul>
   * </ul>
   * @param Object... objects to close.
   */
  public static void close(Object... objects) {
    Exception x = null;
    for(Object object : objects) {
      if(object==null) continue;
      try {
        Invoker.invoke(object, "close", new Object[]{} );
      } catch (NoSuchMethodException eaten) {
        // do nothing
      } catch (Exception e) {
        e.printStackTrace();
        x = e;
      }
    }
    if(x!=null) throw new RuntimeIOException(x.getMessage(), x);
  }

}

try{stream1.close();}catch{} try{stream2.close();}catch{}一般的なコップアウトとは異なり、最後のクローズ例外が存在する場合でもスローされることに注意してください。

乾杯。キース。

于 2012-11-05T04:56:59.180 に答える