java 在java中捕获IOException后如何关闭文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2649322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I close a file after catching an IOException in java?
提问by DimDom
All,
全部,
I am trying to ensure that a file I have open with BufferedReader is closed when I catch an IOException, but it appears as if my BufferedReader object is out of scope in the catch block.
我试图确保在捕获 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 complains that it "cannot find symbol fileIn" in the catch block, but I want to ensure that in the case of an IOException that the Reader gets closed. How can I do that without the ugliness of a second try/catch construct around the first?
Netbeans 抱怨它在 catch 块中“找不到符号 fileIn”,但我想确保在 IOException 的情况下,Reader 被关闭。如果没有围绕第一个的第二个 try/catch 构造的丑陋,我怎么能做到这一点?
Any tips or pointers as to best practise in this situation is appreciated,
任何有关在这种情况下的最佳实践的提示或指示表示赞赏,
回答by Yishai
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;
A few things about the above code:
关于上述代码的一些事情:
- close should be in a finally, otherwise it won't get closed when the code completes normally, or if some other exception is thrown besides IOException.
- Typically you have a static utility method to close a resource like that so that it checks for null and catches any exceptions (which you never want to do anything about other than log in this context).
- The return belongs after the try so that both the main-line code and the exception catching have a return method without redundancy.
- If you put the return inside the finally, it would generate a compiler warning.
- close 应该在finally 中,否则当代码正常完成时,或者抛出IOException 之外的其他异常时,它不会被关闭。
- 通常,您有一个静态实用程序方法来关闭这样的资源,以便它检查 null 并捕获任何异常(除了在此上下文中登录之外,您永远不想做任何其他事情)。
- return 属于 try 之后,这样主线代码和异常捕获都有一个没有冗余的 return 方法。
- 如果你把 return 放在 finally 里面,它会生成一个编译器警告。
回答by purecharger
Once you hit the catch block, any variables declared in the try are not scoped anymore. Declare BufferedReader fileIn = null; above the try block, then assign it inside. In your catch block, do if(fileIn != null) fileIn.close();
一旦你碰到了 catch 块,在 try 中声明的任何变量都不再是作用域了。声明 BufferedReader fileIn = null; 在 try 块上方,然后将其分配到内部。在您的 catch 块中,执行 if(fileIn != null) fileIn.close();
回答by Yuliy
It's complaining about the symbol not being there because it's not. It's in the try block. If you want to refer to fileIn, you'll need to declare it outside the try.
它抱怨符号不存在,因为它不存在。它在 try 块中。如果要引用 fileIn,则需要在 try 之外声明它。
However, it really sounds like you'd want to place the close in a finally block instead: you should close the file regardless of success or failure before returning.
但是,听起来您确实希望将关闭放在 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;
}
回答by DaveJohnston
My preferred way of performing clean-up after an exception (when the clean-up can potentially also throw an exception) is to put the code in the try block inside another try/finally block, as follows:
我在异常之后执行清理的首选方法(当清理也可能引发异常时)是将代码放在另一个 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.
}
}
回答by Mr_and_Mrs_D
It's better not to deal with null- the general idiom for resource acquisition and release in Java is:
最好不要处理null- Java 中资源获取和释放的一般习惯用法是:
final Resource resource = acquire();
try { use(resource); }
finally { resource.release(); }
so:
所以:
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;
}
See my points here
在这里查看我的观点
If you are using a reader you mustspecify the encoding as I am doing here. If you want to read bytes forget about the reader. Also if you use readLine()you must forget about the end of line characters - if this is a concern consider omitting the BufferedReaderentirely.
如果您使用的是阅读器,则必须像我在这里所做的那样指定编码。如果您想读取字节,请忘记阅读器。此外,如果您使用,readLine()您必须忘记行尾字符 - 如果这是一个问题,请考虑BufferedReader完全省略。
回答by John ClearZ
Declare the BufferedReader outside the try block and set it to null then use a finally block to close it if its not null. Also fileArrayList is passed by reference so any changes made to it will happen to the object you passed in so there is no need to also return it.
在 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.
}
回答by Kaleb Pederson
Move the declaration out of the try block:
将声明移出 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.
}
}
But, you'll still need to be careful that fileInwas actually initialized before trying to close it:
但是,fileIn在尝试关闭它之前,您仍然需要小心它实际上已经初始化:
if (fileIn != null)
fileIn.close();

