1

我正在尝试在 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;
    }
}
4

4 回答 4

3

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

  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;
        }
    }
}
于 2014-08-13T21:32:46.337 回答
2

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

您可能有兴趣使用try with resources

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

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

于 2014-08-13T21:27:41.637 回答
1

您应该将调用close()放在 finally 块中。在当前状态下,您的代码永远不会到达最终的 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);
    }

}
于 2014-08-13T21:27:30.413 回答
0

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

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

于 2014-08-13T21:35:48.093 回答