如果流没有手动关闭,什么时候关闭?
When does a stream close if its not closed manually?
我想知道如果流没有手动关闭,它什么时候关闭。我的意思是,如果流的引用范围不再存在,流是否会被关闭?
考虑以下示例场景。
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()
但是依次处理的程序不会终止并继续进行其他操作。
我没有关闭流。 classA的引用范围结束后会自动关闭吗? (即 myMethod()
何时结束)? GC 会处理这个吗?另外,我读到一旦进程结束,流就会关闭,系统会释放为它保留的所有资源,供其他进程使用。我们如何检查流是否打开? Java 中有任何 linux 命令或选项可以检查吗?
感谢任何帮助!
我认为 JVM 规范对此没有任何保证。您确实应该 finally
关闭这些资源。
当进程结束时,操作系统将释放与其关联的所有资源(包括内存、文件句柄和网络套接字)。
有 OS 工具可以检查打开的文件和流,例如 lsof
。
这是一种糟糕的编程习惯,是程序员的错误。根据底层数据源的不同,它可能永远不会关闭并且可能会发生泄漏。您必须在完成任何资源后关闭它,在 finally
块中,或者在 Java 7 或更高时使用资源尝试,以确保即使抛出异常也能关闭它。
InputStream in;
OutputStream out;
try {
// Do your stuff with the streams
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
如果您不手动关闭它,那么所有非托管资源都将在进程终止时释放,但这不是推荐或最佳做法。完成后,您应该始终关闭流。
管理流的更好的建议方法是使用 try with resource 选项,如下所示:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
I did not close the streams. Will it be closed automatically once the
scope of the reference to class A ends?
不,它不会自动关闭。
一个很好的参考是:
Better Resource Management with Java SE 7: Beyond Syntactic Sugar
在 FileInputStream
的情况下,有一个 finalize()
方法可以在流被垃圾收集时释放资源。
并不是说您可以或应该依赖它。 FileInputStream
就是这样做的。另一方面,SocketInputStream
覆盖 finalize()
以显式不执行任何操作,依靠 Socket
关闭资源(并且 Socket
没有 finalize()
方法) .
使用Java7,可以在try语句中创建一个或多个“资源”。 “资源”是实现 java.lang.AutoCloseable 接口的东西。此资源将自动关闭并结束 try 块。
您可以查看 this and 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 结构中使用。
不保证只要 JVM 是 运行,资源就会被关闭,您建议的实现非常危险。
我会建议什么。
将 class A 设为 Closeable 并使用 Java 的 tryResourceClose-Statement。
这个例子在这里。
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
离开 try 块后,您将有机会关闭您的资源。
流本身通常不知道它是否打开。
但是,您自己的 class A 可以跟踪流是否关闭。
我想知道如果流没有手动关闭,它什么时候关闭。我的意思是,如果流的引用范围不再存在,流是否会被关闭?
考虑以下示例场景。
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()
但是依次处理的程序不会终止并继续进行其他操作。
我没有关闭流。 classA的引用范围结束后会自动关闭吗? (即 myMethod()
何时结束)? GC 会处理这个吗?另外,我读到一旦进程结束,流就会关闭,系统会释放为它保留的所有资源,供其他进程使用。我们如何检查流是否打开? Java 中有任何 linux 命令或选项可以检查吗?
感谢任何帮助!
我认为 JVM 规范对此没有任何保证。您确实应该 finally
关闭这些资源。
当进程结束时,操作系统将释放与其关联的所有资源(包括内存、文件句柄和网络套接字)。
有 OS 工具可以检查打开的文件和流,例如 lsof
。
这是一种糟糕的编程习惯,是程序员的错误。根据底层数据源的不同,它可能永远不会关闭并且可能会发生泄漏。您必须在完成任何资源后关闭它,在 finally
块中,或者在 Java 7 或更高时使用资源尝试,以确保即使抛出异常也能关闭它。
InputStream in;
OutputStream out;
try {
// Do your stuff with the streams
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
如果您不手动关闭它,那么所有非托管资源都将在进程终止时释放,但这不是推荐或最佳做法。完成后,您应该始终关闭流。
管理流的更好的建议方法是使用 try with resource 选项,如下所示:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
I did not close the streams. Will it be closed automatically once the scope of the reference to class A ends?
不,它不会自动关闭。
一个很好的参考是:
Better Resource Management with Java SE 7: Beyond Syntactic Sugar
在 FileInputStream
的情况下,有一个 finalize()
方法可以在流被垃圾收集时释放资源。
并不是说您可以或应该依赖它。 FileInputStream
就是这样做的。另一方面,SocketInputStream
覆盖 finalize()
以显式不执行任何操作,依靠 Socket
关闭资源(并且 Socket
没有 finalize()
方法) .
使用Java7,可以在try语句中创建一个或多个“资源”。 “资源”是实现 java.lang.AutoCloseable 接口的东西。此资源将自动关闭并结束 try 块。
您可以查看 this and 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 结构中使用。
不保证只要 JVM 是 运行,资源就会被关闭,您建议的实现非常危险。
我会建议什么。 将 class A 设为 Closeable 并使用 Java 的 tryResourceClose-Statement。 这个例子在这里。 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
离开 try 块后,您将有机会关闭您的资源。
流本身通常不知道它是否打开。 但是,您自己的 class A 可以跟踪流是否关闭。