在java中捕获IOException后如何关闭文件?

时间:2010-04-15 22:05:53

标签: java exception-handling try-catch ioexception bufferedreader

所有

我正在尝试确保在捕获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的情况下Reader被关闭。如果没有第一次尝试/捕获构造的丑陋,我怎么能这样做?

对于这种情况下的最佳做法的任何提示或指示表示赞赏,

7 个答案:

答案 0 :(得分:23)

 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并捕获任何异常(除了在此上下文中登录之外,您永远不想做任何事情)。
  • 返回属于try之后,因此主线代码和异常捕获都有一个没有冗余的返回方法。
  • 如果你把回报放在finally中,它会产生一个编译器警告。

答案 1 :(得分:1)

一旦你点击catch块,try中声明的任何变量都不再作用域。 Declare BufferedReader fileIn = null;在try块上方,然后将其分配到内部。在catch块中,执行if(fileIn!= null)fileIn.close();

答案 2 :(得分: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;
}

答案 3 :(得分:1)

我在异常后执行清理的首选方法(当清理可能也会引发异常时)是将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. 
    }
}

答案 4 :(得分: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();

答案 5 :(得分:0)

在try块之外声明BufferedReader并将其设置为null,然后使用finally块关闭它,如果它不为null。 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.
}

答案 6 :(得分:0)

最好不要处理null - the general idiom for resource acquisition and release in Java is

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;
}

查看我的观点here

如果您使用的是阅读器,则必须指定我在此处执行的编码。如果你想读取字节忘记读者。此外,如果您使用readLine(),则必须忘记行尾字符 - 如果这是一个问题,请考虑完全省略BufferedReader