java程序中的资源泄漏

java程序中的资源泄漏,java,bufferedreader,filereader,resource-leak,Java,Bufferedreader,Filereader,Resource Leak,我正试图用java编写一个方法,从一个文件中获取一些信息,看看该文件是否包含用户需要的信息。然而,对于我展示的代码,eclipse表明在“return true;”行中存在资源泄漏,并且“br=new BufferedReader(fr);”从不关闭,尽管我在程序末尾使用了close()方法。很明显我错过了什么。有人能帮我弄清楚发生了什么事吗?非常感谢 import java.io.*; class Help{ String helpfile; Help(String fna

我正试图用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;
    }
}

您应该将对
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);
    }

}

您应该将对
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);
    }

}

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

您可能对使用
尝试资源感兴趣

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

这样,将在资源上自动调用
close
方法。

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

您可能对使用
尝试资源感兴趣

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

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

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

  • 在关闭资源后放置返回(可能将返回结果放在布尔值中)
  • 修改您的代码,将结束放在finally块中,这样任何返回都将仍然执行该代码
  • 数字2通常是一种更为普遍接受的做法,因为如果将来添加更多内容,则仍然可以保证关闭资源(除非发生灾难性事件)


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

  • 在关闭资源后放置返回(可能将返回结果放在布尔值中)
  • 修改您的代码,将结束放在finally块中,这样任何返回都将仍然执行该代码
  • 数字2通常是一种更为普遍接受的做法,因为如果将来添加更多内容,则仍然可以保证关闭资源(除非发生灾难性事件)


    如果您使用的是Java 7,请使用“资源试用”功能:


    如果您使用的是Java 7,请使用资源试用功能:


    在返回真/假之前,您需要关闭,或者将关闭放在finally块中。您可能还想将代码(完成并运行后)发布到。那里的人可能会给你一些关于变量命名、组织和(轻微的)
    if-else if-{if-else-{if-else if-else}}
    nesting problem:)你需要在返回真/假之前关闭,或者将关闭放在finally块中。你可能还对发布你的代码感兴趣(当它完成并工作时)到。那里的人可能会给你一些关于变量命名、组织和(轻微的)
    if-else if-{if-else-{if-else if-else}}
    嵌套问题的好建议:)创建BufferedReader时,您错过了第一次返回false。创建BufferedReader时,您错过了第一次返回false。