跨多种方法关闭多个资源的好方法

时间:2016-01-05 21:17:51

标签: java

我有一个使用多个Closeable资源的类,它在构造函数中打开它们,我希望它们在close()(也从Closeable接口继承)方法中关闭。我想在类似于java.io类的try-with-resources块中使用此类。

示例(这不是实际代码,但显示了两个资源的问题):

public class Foo implements Closeable {
    private final Reader first;
    private final Reader second;

    public Foo(Reader first, Reader second) {
        this.first = first;
        this.second = second;
    }

...

    @Override
    public close() throws IOException {
        first.close();
        second.close();
    }

}

上述代码不正确,因为如果first.close()抛出异常,则second不会被关闭。添加try / finally围绕这些是PITA,如果我有更多的那些它几乎无法管理。

基本上我的问题是:是否有一个库关闭多个资源并记录异常并抛弃最后发现的异常?

我查看了多个(guava CloseablesIOUtils.closeQuitly()),但他们只处理一个资源,我想提供一些资源。

2 个答案:

答案 0 :(得分:0)

我没有测试过这段代码,但它应该适用于任意数量的读者或其他Closable类

package com.ggl.testing;

import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

public class Foo implements Closeable {
    private final Reader first;
    private final Reader second;

    private List<Exception> exceptions;

    public Foo() {
        this.exceptions = new ArrayList<>();
        this.first = createReader("first.txt");
        this.second = createReader("second.txt");

        printExceptions();
    }

    private Reader createReader(String fileString) {
        try {
            return new FileReader(fileString);
        } catch (FileNotFoundException e) {
            exceptions.add(e);
            return null;
        }
    }

    @Override
    public void close() throws IllegalStateException {
        exceptions.clear();

        closeReader(first);
        closeReader(second);

        printExceptions();

        if (exceptions.size() > 0) {
            throw new IllegalStateException();
        }
    }

    private void closeReader(Reader reader) {
        try {
            if (reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            exceptions.add(e);
        }
    }

    private void printExceptions() {
        for (int i = 0; i < exceptions.size(); i++) {
            exceptions.get(i).printStackTrace();
        }
    }

}

答案 1 :(得分:0)

我创建了一个这样的类:

public class Test{

        public static List<Exception> exceptions;
   public static void main(String[] args){  

             exceptions = new ArrayList<Exception>();
             callException("A");
             callException("B");
           for(Exception e:exceptions)
           {
               System.out.println(" "+e);
           }
  }

         public static void callException(String a)
         {
             try
             {
                 if(a.equals("A"))
                     throw new IOException();
                 else
                     throw new NullPointerException(); 
             }
             catch(Exception ioe)
             {
                 exceptions.add(ioe);
             }
         }

}

输出:

java.io.IOException
java.lang.NullPointerException

这显然可以保存所有例外情况。