7

全て、

IOException をキャッチしたときに BufferedReader で開いたファイルが閉じられるようにしようとしていますが、BufferedReader オブジェクトが catch ブロックの範囲外にあるように見えます。

public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
    fileArrayList.removeAll(fileArrayList);

    try {
        //open the file for reading
        BufferedReader fileIn = new BufferedReader(new FileReader(fileName));

        // add line by line to array list, until end of file is reached
        // when buffered reader returns null (todo). 
        while(true){
                fileArrayList.add(fileIn.readLine());
            }
    }catch(IOException e){
        fileArrayList.removeAll(fileArrayList);
        fileIn.close(); 
        return fileArrayList; //returned empty. Dealt with in calling code. 
    }
}

Netbeans は、catch ブロックで「シンボル fileIn が見つかりません」と不平を言っていますが、IOException の場合にリーダーが閉じられるようにしたいと考えています。最初の try/catch 構造の周りに 2 番目の try/catch 構造の醜さなしに、どうすればそれを行うことができますか?

この状況でのベスト プラクティスに関するヒントや指針をいただければ幸いです。

4

7 に答える 7

24
 BufferedReader fileIn = null;
 try {
       fileIn = new BufferedReader(new FileReader(filename));
       //etc.
 } catch(IOException e) {
      fileArrayList.removeall(fileArrayList);
 } finally {
     try {
       if (fileIn != null) fileIn.close();
     } catch (IOException io) {
        //log exception here
     }
 }
 return fileArrayList;

上記のコードに関するいくつかのこと:

  • そうしないと、コードが正常に完了したとき、または IOException 以外の例外がスローされたときにクローズされません。
  • 通常、そのようなリソースを閉じるための静的ユーティリティメソッドがあり、null をチェックして例外をキャッチします (このコンテキストでログに記録する以外に何もしたくない)。
  • return は try の後に属するため、メインライン コードと例外キャッチの両方に冗長性のない return メソッドがあります。
  • return を finally 内に配置すると、コンパイラの警告が生成されます。
于 2010-04-15T22:09:24.223 に答える
1

catch ブロックをヒットすると、try で宣言された変数はスコープされなくなります。BufferedReader fileIn = null; を宣言します。try ブロックの上に配置し、内部に割り当てます。catch ブロックで、 if(fileIn != null) fileIn.close(); を実行します。

于 2010-04-15T22:08:29.717 に答える
1

シンボルが存在しないため、シンボルが存在しないと不平を言っています。それはtryブロックにあります。fileIn を参照したい場合は、try の外で宣言する必要があります。

ただし、代わりにfinallyブロックにクローズを配置したいようです。成功または失敗に関係なく、戻る前にファイルを閉じる必要があります。

public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
    fileArrayList.removeAll(fileArrayList);

    BufferedReader fileIn = null;
    try {
        //open the file for reading
        fileIn = new BufferedReader(new FileReader(fileName));

        // add line by line to array list, until end of file is reached
        // when buffered reader returns null (todo). 
        while(true){
                fileArrayList.add(fileIn.readLine());
            }
    }catch(IOException e){
        fileArrayList.removeAll(fileArrayList); 
    }finally{
        if(fileIn != null) fileIn.close();
    }
    return fileArrayList;
}
于 2010-04-15T22:08:41.697 に答える
1

例外の後でクリーンアップを実行する方法 (クリーンアップが例外をスローする可能性がある場合) は、次のように、別の try/finally ブロック内の try ブロックにコードを配置することをお勧めします。

public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList) {
    fileArrayList.removeAll(fileArrayList);

    try {
        //open the file for reading
        BufferedReader fileIn = null;

        try {
            fileIn = new BufferedReader(new FileReader(fileName));
            // add line by line to array list, until end of file is reached
            // when buffered reader returns null (todo). 
            while(true){
                fileArrayList.add(fileIn.readLine());
            }
        } finally {
            if (fileIn != null) {
                fileIn.close();
            }
        }
    }catch(IOException e){
        fileArrayList.removeAll(fileArrayList);
        return fileArrayList; //returned empty. Dealt with in calling code. 
    }
}
于 2010-04-15T22:16:42.023 に答える
0

宣言を try ブロックの外に移動します。

public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
    fileArrayList.removeAll(fileArrayList);

    BufferedReader fileIn = null;
    try {
        //open the file for reading
        fileIn = new BufferedReader(new FileReader(fileName));

        // add line by line to array list, until end of file is reached
        // when buffered reader returns null (todo). 
        while(true){
                fileArrayList.add(fileIn.readLine());
            }
    }catch(IOException e){
        fileArrayList.removeAll(fileArrayList);
        fileIn.close(); 
        return fileArrayList; //returned empty. Dealt with in calling code. 
    }
}

fileInただし、閉じようとする前に、実際に初期化されていることに注意する必要があります。

if (fileIn != null)
    fileIn.close();
于 2010-04-15T22:07:41.107 に答える
0

try ブロックの外側で BufferedReader を宣言して null に設定し、null でない場合は finally ブロックを使用して閉じます。また、fileArrayList は参照によって渡されるため、渡されたオブジェクトに変更が加えられると、それを返す必要もありません。

    public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
    fileArrayList.removeAll(fileArrayList);
    BufferedReader fileIn = null;
    try {
        //open the file for reading
        fileIn = new BufferedReader(new FileReader(fileName));

        // add line by line to array list, until end of file is reached
        // when buffered reader returns null (todo). 
        while(true){
                fileArrayList.add(fileIn.readLine());
            }
    }catch(IOException e){
        fileArrayList.removeAll(fileArrayList);  
    }finally
    {
       try
       {
           if(fillIn != null)
               fileIn.close();
       }
       catch(IOException e){}
    }
    return fileArrayList; //returned empty. Dealt with in calling code.
}
于 2010-04-15T22:15:16.413 に答える
0

対処しないほうがよいnull- Java でのリソースの取得と解放の一般的なイディオムは次のとおりです。

final Resource resource = acquire();
try { use(resource); }
finally { resource.release(); }

それで:

public static List<String> readFiletoArrayList(String fileName,
        List<String> fileArrayList, String charsetName) {
    fileArrayList.clear(); // why fileArrayList.removeAll(fileArrayList) ?
    try {
        InputStream file = new FileInputStream(fileName);
        try {
            InputStreamReader reader = new InputStreamReader(file, charsetName);
            BufferedReader buffer = new BufferedReader(reader);
            for (String line = buffer.readLine(); line != null; line = buffer
                    .readLine()) {
                fileArrayList.add(line);
            }
        } finally {
            try {
                file.close();
            } catch (IOException e) {
                e.printStackTrace(); // you do not want this to hide an
                // exception thrown earlier so swallow it
            }
        }
    } catch (IOException e) {
        fileArrayList.clear(); // returned empty. Dealt with in client
    }
    return fileArrayList;
}

ここで私のポイントを参照してください

リーダーを使用している場合は、ここで行っているようにエンコーディングを指定する必要があります。バイトを読みたい場合は、リーダーを忘れてください。また、使用するreadLine()場合は、行末文字を忘れる必要があります。これが懸念される場合は、BufferedReader完全に省略することを検討してください。

于 2013-07-18T21:21:58.747 に答える