当前位置 博文首页 > wunlie的博客:关于try-with-resource的 输入输出流自动关闭

    wunlie的博客:关于try-with-resource的 输入输出流自动关闭

    作者:[db:作者] 时间:2021-07-13 19:12

    最近在做代码审核的时候,审核工具提示我将 try-catch-finally 给替换掉,而且根据公司相关要求,该提示的级别还不低,不改不予通过.
    先看看代码吧:

    FileReader fr = null;  
    BufferedReader br = null;
    
    try {
        fr = new FileReader(fileName);
        br = new BufferedReader(fr);
        return br.readLine();
    } catch (Exception e) {
        log.error("error:{}", e);
    } finally {
      if (br != null) {
        try {
          br.close();
        } catch(IOException e){
          log.error("error:{}", e);
        }
      }
    
      if (fr != null ) {
        try {
          br.close();
        } catch(IOException e){
          log.error("error:{}", e);
        }
      }
    }

    审核工具给出的意见是 替换为:

    try (
        FileReader fr = new FileReader(fileName);
        BufferedReader br = new BufferedReader(fr)
      ) {
        return br.readLine();
    }catch (Exception e) {
        log.error("error:{}", e);
    }
    

    或者是:

    try (
        BufferedReader br = new BufferedReader(new FileReader(fileName))
      ) { 
        // no need to name intermediate resources if you don't want to
        return br.readLine();
    }
    catch (Exception e) { 
        log.error("error:{}", e);
    }

    对比代码,不难发现,输入输出流的关闭存在着差异.难道输入输出流不用关闭了吗? 带着这个问题看看源代码,发现

    public class FileInputStream extends InputStream{}
    
    public abstract class InputStream implements Closeable {}
    
    
    /**
     * A {@code Closeable} is a source or destination of data that can be closed.
     * The close method is invoked to release resources that the object is
     * holding (such as open files).
     *
     * @since 1.5
     */
    public interface Closeable extends AutoCloseable {}
    
    
    /**
     * An object that may hold resources (such as file or socket handles)
     * until it is closed. The {@link #close()} method of an {@code AutoCloseable}
     * object is called automatically when exiting a {@code
     * try}-with-resources block for which the object has been declared in
     * the resource specification header. This construction ensures prompt
     * release, avoiding resource exhaustion exceptions and errors that
     * may otherwise occur.
     *
     * @apiNote
     * <p>It is possible, and in fact common, for a base class to
     * implement AutoCloseable even though not all of its subclasses or
     * instances will hold releasable resources.  For code that must operate
     * in complete generality, or when it is known that the {@code AutoCloseable}
     * instance requires resource release, it is recommended to use {@code
     * try}-with-resources constructions. However, when using facilities such as
     * {@link java.util.stream.Stream} that support both I/O-based and
     * non-I/O-based forms, {@code try}-with-resources blocks are in
     * general unnecessary when using non-I/O-based forms.
     *
     * @author Josh Bloch
     * @since 1.7
     */
    public interface AutoCloseable {}
    

    AutoCloseable 顾名思义, 自动关闭流. 从注释中我们可以发现,实现了AutoCloseable并在try()中声明的对象,当try-with-resource代码块执行完的时候,会自动调用close()方法.
    注意: 一个 try-with-resources 语句可以像普通的 try 语句那样有 catch 和 finally 块。在try-with-resources 语句中, 任意的 catch 或者 finally 块都是在声明的资源被关闭以后才运行。

    cs