Java 关闭输入流的正确顺序是什么?
我正在学习一个关于使用输入流读取文件的Java代码示例。我观察到有3个输入流按照Java 关闭输入流的正确顺序是什么?,java,Java,我正在学习一个关于使用输入流读取文件的Java代码示例。我观察到有3个输入流按照fis、bis和dis的顺序初始化(键入FileInputStream、BufferedInputStream,和DataInputStream),依赖性fis只需关闭外部对象(DataInputStream)。它将关闭它所依赖的所有对象。我建议按与打开顺序相反的顺序(因此dis,bis,然后fis),但这不是必需的(只是样式),或者更好一些 您可以使用,而不必担心关闭顺序 public class Buff
fis
、bis
和dis
的顺序初始化(键入FileInputStream
、BufferedInputStream
,和DataInputStream
),依赖性fis只需关闭外部对象(DataInputStream)。它将关闭它所依赖的所有对象。我建议按与打开顺序相反的顺序(因此dis
,bis
,然后fis
),但这不是必需的(只是样式),或者更好一些
您可以使用,而不必担心关闭顺序
public class BufferedInputStreamExample {
public static void main(String[] args) {
File file = new File("C:\\testing.txt");
try(FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis)) {
while (dis.available() != 0) {
System.out.println(dis.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
虽然文档不是100%清晰,但似乎关闭
DataInputStream
就足够了
DataInputStream
和BufferedInputStream
都是FilterInputStream
的子类,下面是它的close()
(Java 7 SE)文档:
关闭此输入流并释放与该流关联的所有系统资源。此方法仅在.close()中执行
此处中的是已包装的流
假设两个类都不重写超类的行为,则关闭DataInputStream
将递归地关闭所有已包装的流。通常只关闭最外层的流DataInputStream
和BufferedInputStream
都是FilterInputStream
的类型,它调用基础流的close方法。因此,不需要显式关闭其他变量,甚至不需要在变量中维护对它们的引用。例如,可以将dis
初始化为:
dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)));
在实践中,假设这些类是根据规范正确实现的,那么无论您是以任何顺序还是多次关闭任何1、任何2或所有3个流都无关紧要,因为:
如上所述,关闭外部流将关闭内部流
关闭已经关闭的流不会造成任何伤害。(InputStream
和OutputStream
实现Closeable
接口,“如果流已经关闭,则调用此方法无效。”)
实际上,只有FileInputStream
需要关闭,因为它是唯一一个打开真正文件系统资源的流,因此是唯一一个打开后会产生明显副作用的流(例如,您无法删除该文件)。BufferedInputStream
和DataInputStream
是普通对象,无论是否关闭,都可以以普通方式对其进行垃圾收集。如果忘记执行垃圾收集,则当垃圾收集时,FileInputStream
也将关闭,但请谨慎地尽快执行,因为无法保证垃圾收集何时发生
因此,您发布的示例设计过度,但并不危险
在现代Java(7+)中,确保关闭示例中所有内容的更优雅的方法,而不是使用finally
块,是使用语句,它允许您一次性声明流、打开流并保证它们的关闭:
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)))) {
while (dis.available() != 0) {
System.out.println(dis.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
如果关闭其中一条,则关闭另一条。通常,您只需要关闭最外面的溪流。他可能指的是这条溪流@shmosel是的,这也是我的回忆。@TimBiegeleisen问题中有链接:)
dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)));
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)))) {
while (dis.available() != 0) {
System.out.println(dis.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}