我将为物理学学生开设Java讲座,我想知道如何正确打开文件。
在我的许多专业应用程序中,我做了类似的事情:
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("file")));
try{
....
}finally {
bufferedWriter.close();
}
这是恕我直言,即读者将始终关闭。
当我为我的学生提供示例时,我想知道如果InputStreamReader
的构造函数将抛出异常会发生什么 - FileInputStream将打开,但它不会被我的代码关闭(因为这些对象是在try-finally块之外创建的。
这是正确的成语,如果是这样,为什么呢?如果打开流不正确,请指出正确的一个!
编辑:我正在寻找既正确且非常容易编写和理解的习语,物理系学生也是编程的初学者。
编辑:愚蠢的我,我复制错误的例子---如果不是读者,我使用Writers它会变得更复杂。
答案 0 :(得分:4)
在Java 7之前,你就是这样做的
InputStream in = null;
try {
in = new FileInputStream("simple.csv");
BufferedReader buf = new BufferedReader(new InputStreamReader(in));
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {}
}
}
对于Java 7,您可以使用Closeable
,例如
try (BufferedReader buf = new BufferedReader(...)) {}
编辑:为什么我不关闭buf
以上?查看BufferedReader.close()
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
in.close();
in = null;
cb = null;
}
}
编辑2:同样的原则适用于作家。但是,如果您真的有兴趣在IOException
发生时刷新流,那么您必须同时检查writer
和stream
null
并尝试分别关闭它们。但是,这提供了许多额外的代码。它可能看起来像这样:
BufferedWriter buf = null;
OutputStream out = null;
try {
out = new FileOutputStream("file");
buf = new BufferedWriter(new OutputStreamWriter(out));
} finally {
if (buf != null) {
try { buf.close(); } catch (IOException ex){}
}
if (out != null) {
try { out.close(); } catch (IOException ex){}
}
}
它不是很漂亮。您可以引入帮助程序来关闭流或查看Java 7或Apache IOUtils
答案 1 :(得分:0)
在这种特殊情况下(嵌套构造函数),FileInputStream
将保持打开状态。你必须这样做(如果你真的需要确保流关闭):
final FileInputStream fis = new FileInputStream("");
try
{
final BufferedReader br = new BufferedReader(new InputStreamReader(fis));
// ...
}
finally
{
fis.close();
}
关闭FileInputStream
就足够了。
编辑:可以将相同的逻辑应用于编写者。如果打开FileOutputStream
失败,它会抛出一个异常,阻止执行try / finally块。如果任何其他编写器构造函数失败,输出流仍然会通过final
子句关闭。