我正在研究一个关于使用输入流读取文件的Java代码示例。我观察到有3个输入流按fis
,bis
和dis
(键入FileInputStream
,BufferedInputStream
和{{1}的顺序初始化相应地),依赖fis< - (依赖) - bis< - (依赖) - dis。我还观察到它们以相同的顺序关闭:DataInputStream
,fis
,然后是bis
。
我的问题是:不应该以REVERSE顺序关闭它们吗?即最近初始化的应该先关闭?
Here是代码示例。我也贴在这里:
dis
答案 0 :(得分:2)
你只需要关闭外部对象(DataInputStream)。它将关闭它所依赖的所有对象。
答案 1 :(得分:2)
我会建议他们打开顺序的反面(所以dis
,bis
然后fis
),但这不是必需的(只是样式)或更好但是 - try-with-resources
喜欢
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();
}
答案 2 :(得分:2)
您可以使用try-with-resources而不用担心结算顺序
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();
}
}
}
答案 3 :(得分:2)
正常的做法是只关闭最外面的流。 DataInputStream
和BufferedInputStream
都是FilterInputStream
,whose close
method specifies的类型,它调用底层流的close方法。因此,您不需要显式关闭其他人,甚至不需要在变量中维护对它们的引用。例如,可以将dis
初始化为:
dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)));
在实践中,假设根据规范正确实现了类,无论是以任何顺序还是以任何次数关闭任何1个,任何2个或全部3个流都无关紧要,因为:< / p>
InputStream
和OutputStream
实现Closeable
接口,whose close
method states&#34;如果流已经关闭,则调用此方法无效。&#34;)< / LI>
FileInputStream
实际需要才能关闭,因为它是唯一一个保持打开真实文件系统资源的流,因此是唯一一个具有可见副作用的流,如果保持打开状态(例如,您无法删除该文件)。 BufferedInputStream
和DataInputStream
是普通对象,可以以普通方式进行垃圾收集,无论是否关闭。如果您忘记了垃圾收集,那么FileInputStream
也将被关闭,但是尽快做到这一点是谨慎的,因为 垃圾时无法保证收集发生。所以你发布的例子是过度设计的,但并不危险。
在现代Java(7+)中,确保关闭示例中所有内容而不是使用finally
块的更优雅的方法是使用try-with-resources语句,它可以让你宣布流,打开它们,并保证关闭,一气呵成:
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(file)))) {
while (dis.available() != 0) {
System.out.println(dis.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
答案 4 :(得分:1)
虽然文档不是100%明确,但看起来关闭DataInputStream
就足够了。
DataInputStream
和BufferedInputStream
都是FilterInputStream
的子类,这里是close()
(Java 7 SE)的文档:
关闭此输入流并释放与该流关联的所有系统资源。此方法只执行 .close()。
此处in
是包裹的流。
假设两个类都没有覆盖超类的行为,关闭DataInputStream
会递归关闭所有包装的流。