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

問題は、プログラムがリソースを閉じる機会を得る前に戻ってくることです。この問題を解決するには、次の 2 つの方法があります。

  1. リソースを閉じた後にリターンを入れます(おそらくリターン結果をブール値に入れることによって)。
  2. コードを変更して、finally ブロックに close を配置し、リターンが行われた場合でもそのコードが実行されるようにします。

番号 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

br.close()メソッド全体に return ステートメントがありますが、最後に a しかありません。コードの流れの中で、メソッドが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 ブロックに入れる必要があります。現在の状態では、true または false を返しているため、コードが最後の try/catch に到達することはありません。

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 に答える