Do we need to close the inputstream explicitely after read ClassLoader.getSystemResourceAsStream? - java

A call to ClassLoader.getSystemResourceAsStream opens an input stream to the underlying resource that gets eventually converted into properties:
Properties build = new Properties();
build.load(ClassLoader.getSystemResourceAsStream(ANT_BUILD));
Do we need to explicitly close the stream after loading the properties?
Had a quick look at java.util.Properties and it doesn't close the stream!

The specified stream remains open after load method returns, so it's your responsibility to close the stream. You need to close the stream explicitly.

Default ClassLoader.getSystemResourceAsStream(String) returns a FileInputStream wrapped into BufferedInputStream.
If you look into FileInputStream sources you will see that it has got finalize method which closes the stream for you.
But of course it's not a good practice to wait for the heap to grow until garbage collector starts to take care of your streams, and you should always try to close streams yourself.

Related

Should I close a stream which I did not create?

If I have stream (InputStream or OutputStream) which I did not create but was rather passed to my method as a parameter, should I be closing that stream? Here's an example:
void method(InputStream in) {
try {
//Do something
}
finally {
if(in != null) {
in.close(); //Is this needed and correct?
}
}
Really, "it depends".
As a general rule, you should not close a stream that you didn't have responsibility for opening, but to give a correct answer we would have to understand the context.
It's very possible that the delegation of responsibility requires your method to consume from and close the stream - if this is the case then it should be explicit in the code.
If your method is named readFromStreamAndClose(InputStream in) then the fact that your method closes the stream is very obvious.
In the case that you open the stream yourself, you can always use a try-with-resources block which will close the stream for you - at the same level of abstraction as it was created. In this case - your method (which is called at a lower level than when the stream was opened) should not close the stream.
Generally it is not recommended to close the stream which is not associated to that class.
Following are the reasons,
Streams passed to that method may be used in some other place.
Reusable streams are available in java. If the stream is closed it
cannot be reopened and reused.
In case of Exception when closing the stream you don't know how to
handle that. Because you are dealing with general inputstream and it
may come from any place like File, Network etc.
The class opens the stream is responsible for closing it.
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
No you don't have to do it because it may be used somewhere further in the code.
You do document the method with: "Closes the stream" and change the name method to like readAndClose.
Or create a parameter boolean closeStream and close if true.
Also if the stream doesnt support mark/seek/reset there's no reason to keep it open.

answer for necessity of flush in I/O streams in java in fileoutputstreams

Hi I need a answer for necessity of flush in I/O streams in java.since in my program with flush and without flush the output is same.ie,every thing is written in to the destination file.then why i need flush?will file input stream consumes buffer memory?
the below is my simple sample program
file = new File("c:/newfile.txt");
fop = new FileOutputStream("c:/newfile.txt");
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
even when i command flush and close it can write the contents in to the file properly..?then y we need flush?and will file outputstream consumes memory?
Close calls flush on the stream, so flush is not needed if you want to close the stream.
Flush is useful if you want to make sure that the data is saved, without closing a stream, e.g. when sending messages over the Internet, or writing to the console. You may notice, that if you write to console with system.out.print(), then the output is not displayed, until you call flush, or until there is a new line in the text (in which case Java will call flush for you).
See more on this question
In fact, FileOutputStream is not buffered, so the data is directly written to the file.
The abstract OutputStream defines flush (an empty method) to accomodate also the needs of buffered streams, so FileOutputStream inherits it.
If you are not certain of the underlying implementation, it is generally good practice to flush the streams before closing them.
Also, in your code there is a little error:
file = new File("c:/newfile.txt");
fop = new FileOutputStream("c:/newfile.txt");
// Will never happen, new FileOutputStream creates the file
if (!file.exists()) {
file.createNewFile();
}
EDIT:
As for the close part of the question:
When you comment out close(), then exiting main() the close method is called by the finalizer (i.e before the stream is garbage collected, a JVM thread calls its finalize() method, which in turn calls the close() method), but you can't sensibly rely on the finalizer: you don't own it and you can't be sure of when it is activated.
Again , best practice is to call close() explicitly.

Is calling flush onFileOutputStream enough?

So of course we must try-catch-finaly any Closable resource.
But I came across some code which sins as follows:
java.util.Properties myProps = ... reads & loads (and doesn't close Stream!)
myProperties.store(new FileOutputStream(myFilePath), null);
System.exit(0);
java.util.Properties.store() flushes the underlying stream (the FileOutputStream)
Will this be enough?
Can you think of a scenario where the file won't be written? assuming that the method passes and no exception is being thrown in 'store'
It is enough in this specific case, but it is nevertheless very bad practice. The FileOutputStream should be closed, not merely flushed.
If you don't want open file references I would close the streams. Flushing only makes sure that all changes are written to file.

FindBugs: "may fail to close stream" - is this valid in case of InputStream?

In my Java code, I start a new process, then obtain its input stream to read it:
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
FindBugs reports an error here:
may fail to close stream
Pattern id: OS_OPEN_STREAM, type: OS, category: BAD_PRACTICE
Must I close the InputStream of another process? And what's more, according to its Javadoc, InputStream#close() does nothing. So is this a false positive, or should I really close the input stream of the process when I'm done?
In this case, you want to close() the Reader, which will close its underlying streams. Yes, it's always good practice to close streams, even if at the moment you know the implementation you're looking at doesn't do anything (though, in fact, it does here!). What if that changed later?
FindBugs is only there to warn about possible errors; it can't always know for sure.
Finally yes, your Java process owns the process and Process object you spawned. You most definitely need to close that and the output stream. Nobody else is using them, and, it's important to do such things to avoid OS-related stream funny business.
InputStream is an abstract class - just because its implementation does nothing doesn't mean that the actual type of object returned by process.getInputStream() doesn't.
It's possible that failing to close the input stream in this particular case would do no harm - but I personally wouldn't count on it. Close it like you'd close any other input stream. Aside from anything else, that makes your code more robust in case you ever decide to change it to read from something else - it would be all too easy to (say) read from a file instead, and not notice that you're not closing the FileInputStream.
I think its always a good practice to close all the streams you open. Preferably in the finally{} block. Since it does nothing as java says, why not call the close() method. Its of no harm.

Does closing a BufferedOutputStream also close the underlying OutputStream?

I am streaming binary data (a CSV file extracted from the database as a Clob) to the browser by calling response.getOutputStream() and would normally wrap the OutputStream in a BufferedOutputStream when copying the data.
Should I close the BufferedOutputStream or will this also close the underlying OutputStream?
[Extra question: Do I need to use a BufferedOutputStream in this case or is the response already buffered?]
Yes, it closes it. As for whether you should close it - are you expecting to write anything else to the response stream? If not, I think it's fine to close it. If you don't close it, you should obviously flush it instead - but I suspect you could figure that bit out for yourself :)
The behaviour is actually inherited from FilterOutputStream. The Javadocs for for FilterOutputStream.close state:
The close method of FilterOutputStream
calls its flush method, and then calls
the close method of its underlying
output stream.
As for whether you should buffer it - I'm not sure that this is well defined. It may be buried in the servlet spec somewhere - and it may even be configurable (sometimes you really don't want buffering, but if you can buffer the whole response it means you can serve a nicer error page if things go wrong after you've started writing).
Closing the BufferedOutputStream will also close the underlying OutputStream. You should close the BufferedOutputStream so that it flushes its contents before closing the underlying stream. See the implementation of FilterOutputStream.close() (from which BufferedOutputStream extends) to convince yourself.
I guess that whether or not the response stream given to your servlet is buffered or not depends on the implementation of your Servlet Container. FWIW I know that Tomcat does buffer its servlet response streams by default, in order to attempt to set the content-length HTTP header.

Categories

Resources