如果未手动关闭流,它何时关闭?

我想知道如果一个流没有手动关闭,它什么时候关闭。 我的意思是,如果它的参考范围不再是,那么流将被关闭吗?

请考虑以下示例场景。

Class A{ InputStream in; OutputStream out; A(){ // Initialize and create the streams. } ... } Class B{ public void myMethod(){ A a = new A(); System.out.println("End of my method.") } ... } 

在这里,一旦我完成了流,我将退出myMethod()但程序反过来进程,不会终止并继续其他操作。

我没有关闭溪流。 一旦A类参考范围结束,它会自动关闭吗? (即当myMethod()结束时)? GC会照顾到这个吗? 此外,我读到,一旦进程结束,流将被关闭,系统将释放为其他进程保留的所有资源。 我们如何检查流是否开放? 是否有来自Java的任何linux命令或选项来检查?

任何帮助表示赞赏!

我不认为JVM规范对此有任何保证。 你真的应该finally关闭这些资源。

当进程结束时,操作系统将释放与其关联的所有资源(包括内存,文件句柄和网络套接字)。

有OS设施可以检查打开的文件和流,例如lsof

如果您没有手动压缩它,那么当进程终止时,将释放所有非托管资源,但这不是推荐的或最佳实践。 完成后,应始终关闭流。

管理流的更好和建议的方法是使用try with resource选项,如下所示:

 try (InputStream input = new FileInputStream(...); Reader reader = new InputStreamReader(input, ...)) { ... } 

我没有关闭溪流。 一旦A类参考范围结束,它会自动关闭吗?

不,它不会自动关闭。

一个很好的参考是:

使用Java SE 7实现更好的资源管理:超越语法糖

FileInputStream的情况下,有一个finalize()方法,当流被垃圾收集时,它将释放资源。

并非你可以或应该依赖它。 这正是FileInputStream作用。 另一方面, SocketInputStream会覆盖finalize()以显式不执行任何操作,依赖于Socket来关闭资源(而Socket没有finalize()方法)。

只要JVM正在运行,就无法保证资源将被关闭。您建议的实现非常危险。

我会建议什么。 使类A成为Closeable并使用Java的tryResourceClose-Statement。 这个例子在这里。 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

离开try-block后,您将有机会关闭资源。

流本身通常不知道它是否打开。 但是,您自己的A类可以跟踪流是否已关闭。

这是一个糟糕的编程习惯,程序员的错误。 根据底层数据源,它可能永远不会关闭,您可能会有泄漏。 当你完成它,在finally块中,或者使用Java 7或更高版本的资源尝试时,你必须关闭任何资源,以确保即使抛出exception它也会被关闭。

 InputStream in; OutputStream out; try { // Do your stuff with the streams } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } 

使用Java 7,您可以在try语句中创建一个或多个“资源”。 “资源”是实现java.lang.AutoCloseable接口的东西。 此资源将自动关闭并且尝试块结束。

你可以看看这个和java doc获取更多信息

 private static void printFileJava7() throws IOException { try(FileInputStream input = new FileInputStream("file.txt")) { int data = input.read(); while(data != -1){ System.out.print((char) data); data = input.read(); } } } 

当try块完成时,FileInputStream将自动关闭。 这是可能的,因为FileInputStream实现了Java接口java.lang.AutoCloseable。 实现此接口的所有类都可以在try-with-resources构造中使用。