【问题标题】:Resource leak in my java program我的 java 程序中的资源泄漏
【发布时间】:2014-08-13 21:23:29
【问题描述】:

我正在尝试在 java 中编写一个方法,我从文件中获取一些信息并查看该文件是否包含用户查找的信息。但是,对于我提供的代码,eclipse 表明我在“return true;”行中存在资源泄漏;并且“br = new BufferedReader(fr);”永远不会关闭,尽管我在程序末尾使用了 close() 方法。显然我错过了一些东西。有人可以帮我弄清楚发生了什么吗?非常感谢!

import java.io.*;

class Help{
    String helpfile;

    Help(String fname){
        helpfile = fname;
    }

    boolean helpon(String what){
        FileReader fr;
        BufferedReader br;
        int ch;
        String topic, info;

        try{
            fr = new FileReader(helpfile);
            br = new BufferedReader(fr);
        }
        catch(FileNotFoundException e){
            System.out.println(e);
            return false;
        }

        try{
            do{
                ch = br.read();
                if(ch=='#'){
                    topic = br.readLine();
                    if(what.compareTo(topic) == 0){
                        do{
                            info = br.readLine();
                            if(info!=null)
                                System.out.println(info);
                        }while((info!= null) && (info.compareTo("")!= 0));
                        return true;
                    }
                }
            }while(ch!=-1);
        }
        catch(IOException e){
            System.out.println(e);
            return false;
        }

        try{
            br.close();
        }
        catch(IOException e){
            System.out.println(e);
        }
        return false;
    }
}

【问题讨论】:

  • 你需要在返回true/false之前关闭,或者把关闭放在finally块中。
  • 您可能也有兴趣将您的代码(当它完成并工作时)发布到Code Review.SE。那里的人可能会就变量命名、组织和(轻微的)if- else if- {if- else- {if- else if- else}} 嵌套问题给你一些很好的指导:)

标签: java bufferedreader filereader resource-leak


【解决方案1】:

问题是您在程序有机会关闭资源之前返回。有两种方法可以解决此问题:

  1. 在关闭资源后放入返回值(可能将返回结果放入布尔值)。
  2. 修改您的代码,将关闭放在 finally 块中,这样任何返回完成后仍将执行该代码。

第 2 点通常是一种更被接受的做法,因为如果您以后添加更多内容,您仍然可以保证关闭资源(除非发生灾难性事件)。

boolean helpon(String what){
    FileReader fr;
    BufferedReader br;
    int ch;
    String topic, info;

    try{
        fr = new FileReader(helpfile);
        br = new BufferedReader(fr);
        do{
            ch = br.read();
            if(ch=='#'){
                topic = br.readLine();
                if(what.compareTo(topic) == 0){
                    do{
                        info = br.readLine();
                        if(info!=null)
                            System.out.println(info);
                    }while((info!= null) && (info.compareTo("")!= 0));
                    return true;
                }
            }
        }while(ch!=-1);
    } catch(IOException e){
        System.out.println(e);
        return false;
    } catch(FileNotFoundException e){
        System.out.println(e);
        return false;
    } finally {
        try {
            if (br != null) {
                br.close();
            }
        } catch(IOException e){
            System.out.println(e);
            return false;
        }
    }
}

【讨论】:

    【解决方案2】:

    您在整个方法中都有 return 语句,但最后只有一个 br.close()。在代码流中可能会返回该方法,而 br 仍处于打开状态。

    您可能有兴趣使用try with resources

    try (
            FileReader fr = new FileReader(helpfile);
            BufferedReader br = new BufferedReader(fr)
        ) 
    {
      //your code
    }
    catch (IOException e)
    {
     //error
    }
    

    这样,close 方法将自动为您调用资源。

    【讨论】:

      【解决方案3】:

      您应该在 finally 块中调用close()。在当前状态下,您的代码永远不会到达最终的 try/catch,因为您返回的是 true 或 false。

      try {
      
          fr = new FileReader(helpfile);
          br = new BufferedReader(fr);
      
          do {
              ch = br.read();
              if(ch=='#'){
                  topic = br.readLine();
                  if(what.compareTo(topic) == 0){
                      do{
                          info = br.readLine();
                          if(info!=null)
                              System.out.println(info);
                      }while((info!= null) && (info.compareTo("")!= 0));
                      return true;
                  }
              }
          }while(ch!=-1);
      
      } catch (IOException e) {
          System.out.println(e);
          return false;
      
      } catch (FileNotFoundException e) {
          System.out.println(e);
          return false;
      
      } finally  {
      
          try {
      
              if (br != null) {
                  br.close();
              }
      
          } catch (IOException e) {
              System.out.println(e);
          }
      
      }
      

      【讨论】:

      • 您在创建 BufferedReader 时错过了第一个返回 false。
      【解决方案4】:

      如果您使用的是 Java 7,请使用 try-with-resources 功能:

      http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        • 2010-09-16
        相关资源
        最近更新 更多