如果一个流没有被手动关闭,它什么时候关闭?



我想知道当一个流关闭,如果它不是手动关闭。我的意思是,如果流的引用范围不再存在,流会被关闭吗?

考虑以下示例场景:

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负责这个吗?此外,我了解到,一旦进程结束,流将被关闭,系统将为其他进程释放为其持有的所有资源。我们如何检查流是否打开?是否有任何linux命令或Java选项来检查?

任何帮助都是感激的!

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

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

有操作系统工具来检查打开的文件和流,如lsof

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

不是说你可以或应该依赖它。这正是FileInputStream所做的。另一方面,SocketInputStream覆盖finalize(),显式地不做任何事情,依靠Socket来关闭资源(Socket没有finalize()方法)。

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

管理流的一个更好的建议方法是像这样使用try和资源选项:

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

我没有关闭流。它会自动关闭吗对A类末端的引用范围?

不,它不会自动关闭。

一个很好的参考是:

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

不能保证只要JVM在运行,资源就会被关闭,您建议的实现是相当危险的。

我的建议。将类A设置为Closeable,并使用Java的tryresourcecclose - statement。例子在这里。https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

离开try-block后,你有机会关闭你的资源。

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

这是一个糟糕的编程实践,是程序员的错误。根据底层数据源的不同,它可能永远不会关闭,并且可能存在泄漏。在finally块中,或者在Java 7或更高版本中使用try with resources,当你使用完任何资源时,你必须关闭它,以确保即使抛出异常也关闭它。

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接口的东西。此资源将自动关闭,try块结束。

你可以查看这个和Java文档获取更多信息

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构造中使用。

相关内容

  • 没有找到相关文章

最新更新