我正在使用围绕FileReader的BufferedReader读取本地文件:
BufferedReader reader = new BufferedReader(new FileReader(fileName));
// read the file
// (error handling snipped)
reader.close();
我是否还需要close()
FileReader
,或者包装器会处理吗?
我见过人们这样做的代码:
FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
// read the file
// (error handling snipped)
bReader.close();
fReader.close();
这个方法是从servlet调用的,我想确保不要打开任何句柄。
答案 0 :(得分:197)
答案 1 :(得分:93)
正如其他人所指出的,你只需要关闭外包装。
BufferedReader reader = new BufferedReader(new FileReader(fileName));
如果BufferedReader
构造函数抛出异常(例如OutOfMemoryError
),则可能会泄漏文件句柄。如果您的应用程序处于此状态,那么清理需要多么谨慎可能取决于您不会剥夺操作系统可能要分配给其他程序的资源的重要性。
如果包装器构造函数可能在Java 5或6中失败,则可以使用Closeable接口:
Reader reader = new FileReader(fileName);
Closeable resource = reader;
try {
BufferedReader buffered = new BufferedReader(reader);
resource = buffered;
// TODO: input
} finally {
resource.close();
}
Java 7代码应使用 try-with-resources 模式:
try (Reader reader = new FileReader(fileName);
BufferedReader buffered = new BufferedReader(reader)) {
// TODO: input
}
答案 2 :(得分:6)
根据BufferedReader源代码,在这种情况下bReader.close调用fReader.close,所以从技术上讲你不必调用后者。
答案 3 :(得分:4)
BufferedReader的源代码显示关闭BufferedReader时底层关闭。
答案 4 :(得分:3)
检查源代码后,我发现了例子:
FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
BufferedReader 对象上的close()方法将调用 Reader 类的抽象close()方法,该方法最终将调用 InputStreamReader中的实现方法 class,然后关闭 InputStream 对象。
因此,只有bReader.close()就足够了。
答案 5 :(得分:0)
你只需要关闭bufferedReader,即reader.close(),它就能正常工作。
答案 6 :(得分:0)
从Java 7开始,您可以使用try-with-resources Statement
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
由于BufferedReader
实例是在try-with-resource语句中声明的,因此无论try语句是正常完成还是突然完成,它都将关闭。因此,您无需在finally
语句中自行关闭它。 (嵌套资源语句也是如此)
这是使用资源的一种推荐方式,有关更多详细信息,请参见documentation
答案 7 :(得分:0)
我迟到了,但是:
BufferReader.java:
public BufferedReader(Reader in) {
this(in, defaultCharBufferSize);
}
(...)
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
try {
in.close();
} finally {
in = null;
cb = null;
}
}
}
答案 8 :(得分:0)
您不需要,需要关闭包装好的读取器/写入器。
如果您查看了文档(Reader.close()
,Writer.close()
),则会在Reader.close()
中看到它说:
关闭流并释放与其关联的所有系统资源。
这只是说它“释放与它关联的所有系统资源”。即使它不能确定,它也可以让您略微下探。并且如果您转到Writer.close()
,则只会声明它本身已关闭。
在这种情况下,我们参考OpenJDK来查看源代码。
在BufferedWriter Line 265中,您会看到out.close()
。因此,它不会自行关闭。还有其他事情。如果您在类中搜索“ out
”的出现,您会注意到在Line 87的构造函数中,out
是编写者,该类包装了它调用另一个构造函数的位置,然后分配了{ {1}}参数是它自己的out
变量。
所以..那其他人呢?您可以在BufferedReader Line 514,BufferedInputStream Line 468和InputStreamReader Line 199看到类似的代码。其他我不知道的东西,但这足以假设他们知道。