When does a stream close if its not closed manually? - java

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!

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.

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

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

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.

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

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.

Related

try-with-resources Statement in Java SE 7 and later

I'm using Java SDK8 and I created an inputStream and outputStream objects.
Prior to Java SE 7, I could use a finally block to ensure that these resources are closed regardless of whether the try statement completes normally or not.
I read that in Java SE 7 and later I can use a try-with-resources statement and in case the resource I'm using implements the interface java.lang.AutoCloseable I don't need to close this resource in the finally block any more.
My questions are:
1. Is it correct that if I'm using a resource that implements the interface java.lang.AutoCloseable I don't need to close it in the finally block and it will be closed even if an exception will be thrown? if so, Is there a precondition that must exist? (e.g. creating the resource inside a try block?)
2. What does the try-with-resources statement exactly mean?
Thanks a lot in advance!!
Is it correct that if I'm using a resource that implements the interface java.lang.AutoCloseable I don't need to close it in the finally block and it will be closed even if an exception will be thrown?
Yes.
if so, Is there a precondition that must exist? (e.g. creating the resource inside a try block?)
The resource must be created within the try-with-resources statement (see below).
What does the try-with-resources statement exactly mean?
Here's a try-with-resources statement:
try (FileReader fr = FileReader(path)) {
// use fr here
}
Note how the initialization of the FileReader is in the try (in the new () part). That's how the statement knows what needs to be closed later.
(More in the tutorial, though I don't like their first example because it relies on A) The fact that the BufferedReader constructor never throws, and B) The fact that BufferedReader will close the FileReader when the BufferedReader is closed. Those are true for BufferedReader, but it's a poor example in the general case.)
The full gritty details, including a translation of what a try-with-resources looks like in the old try/catch/finally format, are in the specification.
Note that you can create multiple resources in the statement; they're closed in reverse order of creation:
try (
FileReader fr =
new FileReader(fileName);
NiftyThingUsingReader nifty =
new NiftyThingUsingReader(fr)
) {
// ...use `nifty` here
}
Although you could write:
try (
NiftyThingUsingReader nifty =
new NiftyThingUsingReader(new FileReader(fileName))
) {
// ...use `nifty` here
}
...you'd have to know for sure that NiftyThingUsingReader(FileReader) never throws an exception, and that NiftyThingUsingReader#close will close the underlying FileReader, because it will not be handled by the try-with-resources itself. If you're unsure, keep them separate, so that the try-with-resources statement closes the FileReader even if the NiftyThingUsingReader(FileReader) constructor throws, and even if NiftyThingUsingReader#close doesn't close it.
The resources don't have to be relying on each other (directly); for instance, this is a fairly common situation where you want both the input and output to be handled:
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName() +
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}

How to delete a file on a method exit in java?

I am trying to figure out how to make sure a temporary file that gets created in a method gets deleted by the time the method returns. I have tried file.deleteOnExit();, but that is for when the program stops, not the method. I have also tried a try and finally block. Is using a finally block the only way to achieve this?
public String example(File file) {
// do some random processing to the file here
file.canWrite();
InputStream() is = new FileInputStread(file);
// when we are ready to return, use the try finally block
try {
return file.getName();
} finally {
is.close();
file.delete();
}
}
I think it looks ugly. Anyone have a suggestion?
As it was mentioned by #BackSlash in your specific case you can just remove file just before return:
file.delete();
return "File processed!";
However in common case if code inside try block can throw exception your approach looks fine. You can also use Aspect Oriented Programming (e.g. using AspectJ) but it looks like overkill in your case.
You can also improve your code by using nice new feature of Java 7. Each instance of Closable will be closed in the end of try block, e.g.:
try (
InputStream in = ...
) {
// read from input stream.
}
// that's it. You do not have to close in. It will be closed automatically since InputStream implements Closable.
So, you can create class AutoDeletableFile that wraps File and implements Closable. The close() method should delete the file. In this code will work exactly as yours:
try (
AutoDeletableFile file = new AutoDeletableFile("myfile.txt");
) {
// deal with file
}
// do nothing here. The file will be deleted automatically since its close() method actually deletes the file.
Well, that's what finally is for.
Of course, in Java7 you can write an AutoCloseable implementation that does the deleting for you and use try-with-resources instead.
If you are using Java 7 you can achieve this by using java.lang.AutoCloseable interface. Details here http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html.
If not then finally is the best and widely used approach for closing/cleaning resources.
Maybe try delete the file at the end of the method (the last line)? This will delete the file right before the method exits if I understand correctly?
File file = new File("file.txt");
file.delete();

Closing inputstreams in Java

I have the following piece of code in a try/catch block
InputStream inputstream = conn.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
My question is that when I have to close these streams in the finally block, do I have to close all the 3 streams or just closing the befferedreader will close all the other streams ?
By convention, wrapper streams (which wrap existing streams) close the underlying stream when they are closed, so only have to close bufferedreader in your example. Also, it is usually harmless to close an already closed stream, so closing all 3 streams won't hurt.
Normally it is ok to just close the most outer stream, because by convention it must trigger close on the underlying streams.
So normally code looks like this:
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
...
in.close(); // when you care about Exception-Handling in case when closing fails
}
finally {
IOUtils.closeQuietly(in); // ensure closing; Apache Commons IO
}
Nevertheless there may be rare cases where an underlying stream constructor raises an exception where the stream is already opened. In that case the above code won't close the underlying stream because the outer constructor was never called and in is null. So the finally block does not close anything leaving the underlying stream opened.
Since Java 7 you can do this:
try (OutputStream out1 = new ...; OutputStream out2 = new ...) {
...
out1.close(); //if you want Exceptions-Handling; otherwise skip this
out2.close(); //if you want Exceptions-Handling; otherwise skip this
} // out1 and out2 are auto-closed when leaving this block
In most cases you do not want Exception-Handling when raised while closing so skip these explicit close() calls.
Edit
Here's some code for the non-believers where it is substantial to use this pattern. You may also like to read Apache Commons IOUtils javadoc about closeQuietly() method.
OutputStream out1 = null;
OutputStream out2 = null;
try {
out1 = new ...;
out2 = new ...;
...
out1.close(); // can be skipped if we do not care about exception-handling while closing
out2.close(); // can be skipped if we ...
}
finally {
/*
* I've some custom methods in my projects overloading these
* closeQuietly() methods with a 2nd param taking a logger instance,
* because usually I do not want to react on Exceptions during close
* but want to see it in the logs when it happened.
*/
IOUtils.closeQuietly(out1);
IOUtils.closeQuietly(out2);
}
Using #Tom's "advice" will leave out1 opened when creation of out2 raises an exception. This advice is from someone talking about It's a continual source of errors for obvious reasons. Well, I may be blind, but it's not obvious to me. My pattern is idiot-safe in every use-case I can think of while Tom's pattern is error-prone.
Closing the outermost one is sufficient (i.e. the BufferedReader). Reading the source code of BufferedReader we can see that it closes the inner Reader when its own close method is called:
513 public void close() throws IOException {
514 synchronized (lock) {
515 if (in == null)
516 return;
517 in.close();
518 in = null;
519 cb = null;
520 }
521 }
522 }
As a rule of thumb, you should close everything in the reverse order that you opened them.
I would close all of them in the inverse order from which you have opened them, as if when opening them would push the reader to a stack and closing would pop the reader from the stack.
In the end, after closing all, the "reader stack" must be empty.
You only need to close the actual resource. You should close the resource even if constructing decorators fails. For output, you should flush the most decorator object in the happy case.
Some complications:
Sometimes the decorators are different resources (some compression implementations use the C heap).
Closing decorators in sad cases actually causes flushes, with ensuing confusion such as not actually closing the underlying resource.
It looks like you underlying resource is a URLConnection, which doesn't have a disconnect/close method as such.
You may wish to consider using the Execute Around idiom so you don't have to duplicate this sort of thing.

Closing Java InputStreams

I have some questions about the usage of the close() method when using Java InputStreams. From what I see and read from most developers, you should always explicitly call close() on an InputStream when it is no longer needed. But, today I was looking into using a Java properties file, and every example I have found has something like this:
Properties props = new Properties();
try {
props.load(new FileInputStream("message.properties"));
//omitted.
} catch (Exception ex) {}
With the above example, there is no way to explicitly call close() because the InputStream is unreachable after it is used. I have seen many similar uses of InputStreams even though it seems to contradict what most people say about explicitly closing. I read through Oracle's JavaDocs and it does not mention if the Properties.load() method closes the InputStream. I am wondering if this is generally acceptable or if it is preferred to do something more like the following:
Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
} finally {
try {
fis.close();
} catch (IOException ioex) {
//omitted.
}
}
Which way is better and/or more efficient? Or does it really matter?
The Properties class wraps the input stream in a LineReader to read the properties file. Since you provide the input stream, it's your responsibility to close it.
The second example is a better way to handle the stream by far, don't rely on somebody else to close it for you.
One improvement you could make is to use IOUtils.closeQuietly()
to close the stream, e.g.:
Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
} finally {
IOUtils.closeQuietly(fis);
}
I would go with a try-with-resources (at least for Java 7+):
Properties props = new Properties();
try(InputStream fis = new FileInputStream("message.properties")) {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
}
The close() call should be automatically called when the try block is exited.
The examples in the Properties Tutorial close the FileInputStream explicitly after loading, so I think it's safe to assume that the load method isn't responsible for it, you are.
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
Just for reference, I checked the Apache Harmony implementation of Properties, and it does not close the stream on load.
If you're using Java 7+ you can use this:
try(InputStream is = new FileInputStream("message.properties")) {
// ...
}
It doesn't mention in the documentation that props.load would close the input stream. You should close the input stream manually in a finally block like you suggest.
It isn't normal for a function to close an InputStream. The same convention applies as with memory in non-garbage-collected languages: If possible, the one who opens the stream should close the stream. Otherwise, it's very easy to leave a stream open (you think a function's going to close it, but it doesn't, or something...)
It looks like the first code sample ends up relying on the finalize method in FileInputStream to actually close the file. I would say your second example is better, even though in both cases the file does get closed.
There are cases like the Byte streams where close does nothing and can be omitted, otherwise I think it's better to explicitly close the file in a finally block. If you open it, you close it.
There is a book on Oracle's site called Java Platform Performance that discusses finalizers in its appendix, it says:
You are almost always better off doing your own cleanup instead of relying on a finalizer. Using a finalizer can also leave behind critical resources that won't be recovered for an indeterminate amount of time. If you are considering using a finalizer to ensure that important resources are freed in a timely manner, you might want to reconsider.
Let me add a little something to other people's answers.
If you can import Apache Commons IO, you could make use of the ever-so-handy AutoCloseInputStreams classes: you wrap your InputStream and then you just use your wrapped instance and it gets automatically closed as soon as the end of input has been reached or when the stream is explicitly closed, whichever comes first.
Because FileInputStream implements finalize() and invoke close() in `finalize.
So when not so frequently used, there is no need to close FileInputStream

Regarding java file closing

i noticed in a java program the below line used to open a file and process it
BufferedReader inp = new BufferedReader(new FileReader(inputFile));
In the javaprogram the inp is not closed before exiting the program the below line is missing
if (inp != null)
try {
inp.close();
} catch (IOException logOrIgnore) {}
The program has exits in a lot of place but they had not closed the file. Do i need to put this line everywhere? If i dont close the file when the program exits will it be a issue.
Does the garbage collector closes the file?
You should use try/finally:
Reader inp = new BufferedReader(new FileReader(inputFile));
try {
// Do stuff with "inp"
} finally {
IOUtils.closeQuietly(inp);
}
IOUtils is from Apache Commons IO. Its closeQuietly method is like your code snippet above: it calls close, and ignores any exceptions thrown.
The garbage collector does not close the file. If you know your program will not be long running or open many files, you can get away without closing the file. But otherwise you need to close it manually.
It sounds like you're using the BufferedReader without returning to the context in which it was declared (possibly an instance variable?). In that instance, you must close it manually upon each possible exit from your application. You cannot rely on the garbage collector to do this for you.

Categories

Resources