Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关闭输入流的正确顺序是什么?_Java - Fatal编程技术网

Java 关闭输入流的正确顺序是什么?

Java 关闭输入流的正确顺序是什么?,java,Java,我正在学习一个关于使用输入流读取文件的Java代码示例。我观察到有3个输入流按照fis、bis和dis的顺序初始化(键入FileInputStream、BufferedInputStream,和DataInputStream),依赖性fis只需关闭外部对象(DataInputStream)。它将关闭它所依赖的所有对象。我建议按与打开顺序相反的顺序(因此dis,bis,然后fis),但这不是必需的(只是样式),或者更好一些 您可以使用,而不必担心关闭顺序 public class Buff

我正在学习一个关于使用输入流读取文件的Java代码示例。我观察到有3个输入流按照
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();
    }