Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it good to close() an inputstream?

Why is it necessary to close() java.io.InputStream or its subclasses?

Now with java.io.OutputStream, say FileOutputStream, after writing to a file, if we don't close() the output stream, the data that we intended to write in the file remains in the buffer and is not written to the file.

So it becomes necessary to close() an OutputStream. But i never had any bitter experiences after not closing an InputStream.

But still all articles on the internet and books say that it is always good to close any Stream may it be an InputStream or an OutputStream.

So my question is that why does it become necessary to close() an InputStream? People say that you may face a memory leak of you don't close() it. So what kind of a memory leak is that?

like image 342
Aditya Singh Avatar asked Oct 24 '14 04:10

Aditya Singh


People also ask

Why should we close InputStream?

You do need to close the input Stream, because the stream returned by the method you mention is actually FileInputStream or some other subclass of InputStream that holds a handle for a file. If you do not close this stream you have resource leakage.

Why do we close InputStream in java?

The java. io. InputStream. close() method closes this stream and releases any system resources associated with the stream.

Why should you always close streams?

If you don't close streams, you may have problems opening them back up again. This is especially true if they're hanging off the end of sockets. Closing a stream also makes sure that data is flushed through the stream if there is any data left to send.


1 Answers

An InputStream ties up a tiny kernel resource, a low level file handle. In addition, the file will be locked to some extent (from delete, renaming), as long as you have it open for read. Lets imagine you didn't care about the locked file. Eventually, if you need to read another file, and open it with a new InputStream, the kernel sequentially allocates a new descriptor (file stream) for you. This will eventually add up. If it is a long running program then it is just a matter of time until your program fails.

The file descriptor table for a processor is typically of limited size. Eventually the file handle table will run out of free slots for the process. Even in the thousands, you can still easily exhaust this for a long running application, at which point, your program can no longer open a new file or socket.

The process file descriptor table is as simplistic as something like:

IOHANDLE fds[2048];  // varies based on runtime, IO library, etc. 

You start with 3 slots occupied (STDIN, STDOUT, STDERR). Also any network sockets and other types of IPC will use a slot in the same table. Fill that up and you have performed a denial of service on your program.

All that is nice to know; how best to apply it?

If you rely on local objects to go out of scope, then its up to the Garbage Collector, which can reap it in its own sweet time (nondeterministic). Don't rely on the GC, close the streams explicitly.

With Java, you want to use try-with-resources on types that implement java.lang.AutoCloseable, "which includes all objects which implement java.io.Closeable" per the docs: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

With C#, the equivalent is a "using" block on objects that implement IDisposable

like image 105
codenheim Avatar answered Oct 23 '22 01:10

codenheim