When does a stream close if its not closed manually?
Asked Answered
P

6

14

I would like to know when does a stream close if its not closed manually. By this I mean, will the stream be closed if the scope of its reference is no more?

Consider the following sample scenario.

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.")
 }
...
}

Here, once I am done with the stream, I am exiting myMethod() but the program which in turn the process, is not terminated and goes on with other operations.

I did not close the streams. Will it be closed automatically once the scope of the reference to class A ends? (ie. When myMethod() ends)? Does GC takes care of that? Also, I read that the streams will be closed once the process ends and the system releases all the resources held for it for other processes. How can we check whether the stream is open or not? Are there any linux commands or options from Java to check that?

Any help is appreciated!

Prater answered 22/10, 2015 at 7:47 Comment(2)
As a rule, you should always close all streams (and Closeables in general) in a finally block (or try-with-resources)Dendrite
At this very point, I sit back in my chair, and I am trying to remember all Java streams I opened, and I assumed that they automatically closed out of the scope. For last 15 years. Then, I rise up and scream "C++ I love you so hard".Arnoldoarnon
S
15

I don't think that the JVM spec makes any guarantee about that. You really are supposed to finally close these resources.

When the process ends, the operating system will release all resources associated to it (including memory, file handles, and network sockets).

There are OS facilities to check about open files and streams, such as lsof.

Situated answered 22/10, 2015 at 7:51 Comment(2)
Yes, I am closing it in finally block, but asked out of curiosity. But don't you think GC should be configured to take care of this also? Because, once the scope of a reference ends, all the streams referenced by it along with the memory should be garbage collected. Isn't it?Prater
Yes, GC will eventually happen. But it is not guaranteed to be timely, and it is not completely guaranteed to run the finalizer (which would close the stream). The stance is that the developer is supposed to take care of it.Situated
D
7

In the case of FileInputStream there's a finalize() method that will free resources when the stream is garbage collected.

Not that you can or should rely on that. It's just what FileInputStream does. SocketInputStream on the other hand overrides finalize() to explicitly do nothing, relying on Socket to close the resources (and Socket doesn't have a finalize() method).

Dixiedixieland answered 22/10, 2015 at 7:56 Comment(0)
B
5

If you are not clossing it manually then all the unmanaged resources will be released when the process termiantes, however it is not a recommended or a best practice. You should always close your stream once you are done with it.

A better and suggested way to manage the stream is to use try with resource option like this:

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?

No it will not close automatically.

A good reference to follow is:

Better Resource Management with Java SE 7: Beyond Syntactic Sugar

Ballflower answered 22/10, 2015 at 7:52 Comment(0)
H
2

There is no garantee that the resources will be closd as long as the JVM is running, Your suggested implementation is quite dangerous.

What I would suggest. Make the class A a Closeable and use the tryResourceClose-Statement of Java. The example is here. https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

After leaving the try-block you get the chance to close your resources.

The stream itself normally doesn't know if it is open or not. However, your own class A can keep track it the streams were closed or not.

Higgins answered 22/10, 2015 at 8:0 Comment(0)
U
0

That's a bad programming practice, an error from the programmer. Depending on the underlying data source, it might never close and you can have leaks. You MUST close any resource when you've finished with it, in a finally block, or using a try with resources if Java 7 or higher, to ensure it is closed even if an exception is thrown.

InputStream in;
OutputStream out;
try {
   // Do your stuff with the streams
} finally {
   if (in != null) {
       in.close();
   }
   if (out != null) {
       out.close();
   }
}
Ujiji answered 22/10, 2015 at 7:51 Comment(0)
E
0

With Java 7, you can create one or more “resources” in the try statement. A “resources” is something that implements the java.lang.AutoCloseable interface. This resource would be automatically closed and the end of the try block.

you can look this and java doc for more info

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();
        }
    }
}

When the try block finishes the FileInputStream will be closed automatically. This is possible because FileInputStream implements the Java interface java.lang.AutoCloseable. All classes implementing this interface can be used inside the try-with-resources construct.

Eugenol answered 22/10, 2015 at 7:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.