Как я закрываю файл после ловли IOException в Java?

Все,

Я пытаюсь удостовериться, что файл, который я имею открытый с BufferedReader, закрывается, когда я ловлю IOException, но появляется, как будто мой объект BufferedReader вне объема в блоке выгоды.

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 жалуется, что "не может найти символ fileIn" в блоке выгоды, но я хочу удостовериться, что в случае IOException, что Средство чтения закрывается. Как я могу сделать это без уродства второй конструкции попытки/выгоды вокруг первого?

Любые подсказки или указатели относительно наиболее успешной практики в этой ситуации ценятся,

7
задан jjnguy 19 October 2010 в 19:46
поделиться

6 ответов

 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;

Несколько моментов о приведенном выше коде:

  • close должно быть в finally, иначе он не закроется, когда код завершится нормально или если возникнет другое исключение. выброшенный помимо IOException.
  • Обычно у вас есть статический служебный метод для закрытия такого ресурса, чтобы он проверял наличие null и улавливал любые исключения (которые вы никогда не хотите делать, кроме регистрации в этом контексте).
  • Возврат выполняется после попытки, так что и основной код, и перехват исключения имеют метод возврата без избыточности.
  • Если вы поместите return внутрь finally, компилятор выдаст предупреждение.
23
ответ дан 6 December 2019 в 06:49
поделиться

Мой предпочтительный способ выполнения очистки после исключения (когда очистка потенциально также может вызвать исключение) - это поместить код в блок try внутри другого блока try / finally, как показано ниже:

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. 
    }
}
1
ответ дан 6 December 2019 в 06:49
поделиться

Объявите BufferedReader вне блока try и установите для него значение 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.
}
0
ответ дан 6 December 2019 в 06:49
поделиться

Он жалуется на отсутствие символа, потому что его нет. Это в блоке попытки. Если вы хотите сослаться на fileIn, вам нужно объявить его вне попытки.

Однако это действительно похоже на то, что вместо этого вы захотите поместить закрытие в блок 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;
}
1
ответ дан 6 December 2019 в 06:49
поделиться

Как только вы попадаете в блок catch, любые переменные, объявленные в try, больше не имеют области видимости. Объявить BufferedReader fileIn = null; над блоком try, затем назначьте его внутри. В блоке catch выполните if (fileIn! = Null) fileIn.close ();

1
ответ дан 6 December 2019 в 06:49
поделиться

Переместите объявление из блока 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();
0
ответ дан 6 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: