想象一下,MyOpenedFile是包含已打开流的文件的东西。然后假设这段代码:
// method in an Util class
static void safeClose(MyOpenedFile f) {
if (f != null) {
try {
f.close();
} catch(IOException ex) { /* add logging or console output */ }
}
}
问题的实际方法:
void doSomeFileOperation(...) throws IOException, ... {
MyOpenedFile f1 = null;
MyOpenedFile f2 = null;
try {
/* method's "business logic" code beings */
f1 = new MyOpenedFile(...);
//do stuff
f2 = new MyOpenedFile(...);
// do stuff
f1.close(); f1 = null;
// do stuff with f1 closed
f2.close(); f2 = null;
// do stuff with f2 closed
/* method's "business logic" code ends */
} finally {
Util.safeClose(f1); f1 = null;
Util.safeClose(f2); f2 = null;
}
}
现在这非常混乱,特别容易出错(例如,在单元测试中,finally块中的某些代码可能很难被调用)。例如,在C ++中,析构函数将负责清理(由scoped指针析构函数调用或直接调用),代码将更加清晰。
那么,是否有更好/更好/更清洁的方式来包装上面的业务逻辑代码,以便传播任何异常,但文件f1
和f2
都关闭(或至少关闭是尝试两者,即使它失败了)?
也指向任何开源库,如Apache Commons,欢迎提供好的包装。
答案 0 :(得分:4)
文件是String的包装器,其中包含可能存在或不存在的文件名。它是无国籍的,所以你不需要关闭它。
您需要关闭的资源是FileInputStream或BufferedReader,您可以在Java 7中使用ARM隐式关闭这些资源
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
}
当他阻止退出时,这将关闭br
。
http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html
答案 1 :(得分:1)
看一下The try-with-resources Statement,它将在try-block结束后关闭资源。
您使用的File
类似乎不是java.io.File
,因为它没有任何close()
方法。在这种情况下,请确保您自己的File
类实现Closeable
以使其与ARM一起使用。
try (FileInputStream f1 = new FileInputStream("test1.txt");
FileInputStream f2 = new FileInputStream("test2.txt")) {
// Some code
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
答案 2 :(得分:1)
你不需要关闭文件(这是文件系统上文件的表示),如下所述:
Do I need to close files I perform File.getName() on?
我假设您要求更多关于文件流/读者的信息?
在这种情况下,java 7有一个很好的新功能: http://www.vineetmanohar.com/2011/03/java-7-try-with-auto-closable-resources/
如果你正在使用旧版本的java,我只想简单地说:
void doSomeFileOperation(...) throws IOException, ... {
FileInputStream f1 = null;
FileInputStream f2 = null;
try {
// do stuff
} finally {
Util.safeClose(f1);
Util.safeClose(f2);
}
}
答案 3 :(得分:0)
自动出现的选项是:将处理文件的代码与执行任何处理的代码分开。通过这种方式,您可以封装处理打开,关闭和异常处理的讨厌代码。
另一点是你的样本做了很多额外的,不必要的步骤
void doSomeFileOperation(...) throws IOException, ... {
File f1 = null;
File f2 = null;
try {
f1 = new File(...);
f2 = new File(...);
// callback to another class / method that does the real work
} finally {
Util.safeClose(f1);
Util.safeClose(f2);
}
}
您无需将File实例设置为null。如果您尝试使用它们,您将获得例外。
我不知道你正在使用的File
对象。 java中的标准File
类没有close()
方法。