Do we really need to call flush() just before close() today? - java

I read this question Using flush() before close() , and the accepted answer is this only means you follow the pattern.
Just like BufferedWriter#close() or FilterOutputStream.#close() , if all of buffered Stream/Writer will call its flush() when we call close() and if we (the dev and the dev who will review the code) all know the that, do we really still need this? If yes, what will be the reason?

As the javadoc says, you don't need to flush yourself.
But, it's still good to do, considering your readers, and common sense.
Few experts know the javadoc by heart.
I wouldn't know for sure if the stream will be flushed or not without looking it up,
and I'm probably not alone.
Seeing the explicit flush() call makes this perfectly clear,
and therefore makes the code easier to read.
Furthermore, the method name close() implies nothing about flushing.
It's from the Closeable interface,
and naturally, it says nothing about flushing.
If you don't flush a buffered output stream before closing,
despite wanting to flush it,
you'll be relying on assumptions that may or may not be true.
It would weaken your implementation.
Any assumptions you make,
you should somehow pass on to future maintainers.
One way to do that is by leaving a comment:
// no need to flush() manually, close() will do it automatically
If you don't leave this comment,
future maintainers may have to lookup the javadoc too,
if like me they don't have it memorized.
But then, why would you write such comment when it's easier and better to just call it yourself now and be done with it.
In short, flushing first before closing is simply following good logic.
No need for assumptions and second guesses,
and no need to make your readers think.

For output, it is important that we do call flush() and close() because buffered data could be lost, as explained by the first answer here. If your program's output is smalland your writer finishes quickly, it won't make much difference to close() and flush() in my experience.
For input, it won't matter if we don't call close() before the system exits.

Related

what is the proper way to close streams on java's exec?

After
Runtime.getRuntime().exec(command);
i see syscalls happening that show 2~3 file descriptors (FIFO pipes). What is the proper way to close them with try-with-resource pattern?
Most historical tribal knowledge found on java forums suggest:
# out of date!
... } finally {
IOUtils.closeQuietly(p.getOutputStream());
IOUtils.closeQuietly(p.getInputStream());
IOUtils.closeQuietly(p.getErrorStream());
}
but that doesn't sound right because 1) method closeQuietly is deprecated and most libraries suggest using try-with-resource, 2) it is inelegant as I might not necessarily have all streams.
And simply moving the exec() call into try feels wrong as it is not the resource i will call close() on.
Closing them isn't necessary; the close by themselves when the process dies. If the process never dies, it is also not neccessary: Either you make a new never-dying process every so often in which case your system is going to crash and run out of resources whether you close these or not, or you make it only once, in which case these resources aren't going to count for much. For what it is worth, these are quite lightweight resources, and often they simply cannot be 'closed' in the sense that the resources can be 'freed' - closing them either keeps them open but denies further chat (and sends EOFs where needed), or reroutes them to /dev/null; generally processes just have 3 pipes on em and will continue to have them until the process dies.
Yes, closeQuietly is a silly idea for virtually all purposes, and so it is here. If closing these streams somehow fail you probably don't want to silently ignore that.
If you must close them, the individual streams from these 3 are closable. However, note that you're reading rules of thumb and attempting to apply them as if they are gospel truth. try-with-resources is not always the right answer, and try-with-resources is not a 100% always replacement for close, let alone closeQuietly.
For example, try-with-resources specifically is designed around a period of usage. You declare the span of statements within which the resource should be available (the braces that go with the try block), and the construct will then ensure that the resource is closed only once code flow transitions out of that span of statements, no matter how it exits this. That makes it probably irrelevant here, too!
You are starting a long-lived process and don't care about the in/out. You just want the process to run and to keep running. This means there is no span at all, and you should just call close() on these if somehow you feel it is important to try to save the resources even though most likely this accomplishes nothing at all. No span-of-statements means try-with-resources isn't right.
You are starting a short-lived process that you interact with. The right thing to 'close' is the process itself, except you can't use try-with-resources for that. That can only be used on auto-closables. (resources where the class that represents them implement AutoClosable. Most do, some don't. Lock is a famous one. Process is another: To 'close' it, you invoke destroy() or even destroyForcibly(). You cannot use try-with-resources (not without ugly hacks that defeats the purpose) to do this! Once you close/destroy the process, the streams that went along with them are dead too.
More generally the principle is: If you create it, you close it. If you never call getOutputStream() you never created them. On some OSes, fetching these streams and then closing them wastes more resources than not doing this. Thus, if the argument is based on some sort of purity model, then you shouldn't close them either. If it's based on pragmatics, you'd have to test how heavy these resources really are (most likely, extremely light), whether closing them actually saves you some pipes (most likely, it will not), and whether close()-ing the result of invoking getOutputStream() on the process even helps if the answers to the above questions make that relevant (it probably will, but the spec does not guarantee this).
They are very light processes that in almost every case don't require closing...

Will netty automatically flush writed data?

Recently I was writing a http server and I transplanted some netty components to my project. When I read the source code of netty's ChannelHandlerContext, I found that actually it doesn't flush into socket. I knew that I have to invoke flush() to flush the internal buffer into socket.
So I wonder will netty automatically flush the internal buffer, I have read some source code, but I am not good at it. And I googled but none answered it, the only answer I got is do flushing.
What I have learned from source code is: write continue writing into outboundbuffer, and if outboundbuffer reaches highwatermark, it will fire writability changed event and the channel is unwritable.
You can call the writeAndFlush method if you want to do it in one line, but otherwise you need to flush or you data will not go through.
4.0 introduced a new operation called flush() which explicitly flushes the outbound buffer of a Channel, and write() operation does not flush automatically. You can think of this as a java.io.BufferedOutputStream, except that it works at message level.
Because of this change, you must be very careful not to forget to call ctx.flush() after writing something. Alternatively, you could use a shortcut method writeAndFlush().
I found it at https://netty.io/wiki/new-and-noteworthy-in-4.0.html#write-does-not-flush-automatically
In fact, I have the similar question at Why did not call ctx.flush() after ctx.write() is called at Netty user guide?
Please contact me if you got the answer.
No, it won't.
However, it could be implemented quite easily.
As you said:
What I have learned from source code is: write continue writing into
outboundbuffer, and if outboundbuffer reaches highwatermark, it will
fire writability changed event and the channel is unwritable.
It's right. and it in fact tells a way to automaticallly flush. Just override ChannelInboundHandler.channelWritabilityChanged to call flush().

Using flush() before close()

As per the java docs, invoking close() on any java.io Streams automatically invokes flush(). But I have seen in lot of examples, even in production codes, developers have explicitly used flush() just before close(). In what conditions we need to use flush() just before close()?
Developer get into a habit of calling flush() after writing something which must be sent.
IMHO Using flush() then close() is common when there has just been a write e.g.
// write a message
out.write(buffer, 0, size);
out.flush();
// finished
out.close();
As you can see the flush() is redundant, but means you are following a pattern.
I guess in many cases it's because they don't know close() also invokes flush(), so they want to be safe.
Anyway, using a buffered stream should make manual flushing almost redundant.
I want to point out an important concept that many previous comments have alluded to:
A stream's close() method does NOT necessarily invoke flush().
For example org.apache.axis.utils.ByteArray#close() does not invoke flush().
(click link to see source code)
The same is true more generally for any implementations of Flushable and Closeable. A prominent example being java.io.PrintWriter. Its close() method does NOT call flush().
(click link to see source code)
This might explain why developers are cautiously calling flush() before closing their streams. I personally have encountered production bugs in which close() was called on a PrintWriter instance without first calling flush().
The answers already provided give interesting insights that I will try to compile
here.
Closeable and Flushable being two independent traits, Closeable do not specify that close() should call flush(). This means that it is up to the implementation's documentation (or code) to specify whether flush() is called or not. In most cases it is the norm, but there is no guaranty.
Now regarding what #Fabian wrote: It is true that java.io.PrintWriter's close() method does not call flush(). However it calls out.close() (out being the underlying writer). Assuming out is a BufferedWriter, we are fine since BufferedWriter.close() is flushing (according to its doc). Had it be another writer, it may not have been the case...
So you have two choices:
either you ensure that at least one inner Writer/Stream flushes by itself (beware in case of code refactoring),
or you just call flush() and you're on the safe side all the time.
Solution 2, requiring less work, is my preferred one.

Clean up code in finalize() or finally()?

I had the general view that clean up of resources is done in the finally block,
recently I found this particular code snippet in a class and it was overriding the Object class' finalize() method.
protected void finalize() {
try {
In.close();
Out.close();
socket.close();
}
catch (Exception e) {
//logger code here
}
}
Is this a good idea? What are the pros and cons of finalize() over finally?
The finally block is just a block of code that always executes after a try block, even if there is an exception. i.e. it is local in scope
The finalize() method is an approach for cleaning up the whole object when it is garbage collected.
Java documentation of finalize()
finally solves the problem of cleaning up resources in a block of code regardless of whether an exceptional condition occurs...
finalize() is a way to clean up resources when your object is no longer being used, once the Garbage Collecter determines there are no more references to that object.
In short, to answer your question, for example, if the sockets you are closing are members of an object you should close them in the finalize() method, (although that's sub-optimal, and just for example, because there is no guarantee when the GC will actually perform the action)
If however you're opening the socket in a method, and are done with it when the method ends you should free the resources in the finally block.
Always clean up things in finally.
Cleaning up in finalize is not guaranteed to occur.
However, it is often found to clean up such things in finalizers as a last-ditch safety valve should a finally block throw another exception on you.
The real problem with relying on finalizers is something else may need the resource before the GC gets around to calling the finalizer.
Phantom References will do what you want.
Just don't use finalize. There are a few edge cases where it may be helpful (printing debug info when a class is GC'd has come in handy), but in general don't. There is nothing in the JVM contract that even says it ever has to be called.
There is a very under-publicized type of object called "References". One is made explicitly for things that you think you would use finalize for.
"Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed."
It just occurred to me that there MUST be a description of this on the web--so I'll replace all the "how-to" stuff I just wrote with this reference.
They're not related. This is like asking, "Should you create objects in an initializer or in normal methods?" Like, it depends on what you're doing with the objects. A finalizer cleans up an object's state while it's destroyed (maybe — it's not something you should rely on), while a finally block executes code after a try block. There isn't any common situation where you'd be able to choose one or the other since they do different things.
Finalize is probably a bad idea if your application causes lots of these objects to be created. This is because finalize will cause a bottleneck as the objects become eligible for garbage collection.
There are times when finalize is the only solution; but use finally whenever you can
Finally. Finalize is bad in that it may never get called. Use finalize only as a safety net. For example an InputStream should have a finalize that closes the stream incase the applcicationforgets to. However the application should close it.
If it were me I would do the cleanup in the finalizer as well and log the cases when the cleanup was performed and then track down in the application the code that forgot to properly clean up.
There are a number of problems with the code in the question, including:
The big problem: It looks like you are trying to close a socket. Even if you don't close it properly, it will close in its own finaliser. Adding another finaliser doesn't make it any more closed.
An exception thrown by the first close will prevent the others from executing (as it happens, this doesn't matter in this example because of the peculiar behaviour of Socket).
If you do override finalize, leave it throwing Throwable (and add #Override). Technically you should also call the super in a finally block.
The Java Memory Model is mighty strange when it comes to finalisers (previous execution of code does not necessarily happen-before the execution of the finaliser). I would explain the problem, but what you need to know is that you need to stay away from finalisers.
So: Always use finally for these things. finalize is extremely specialised (and PhantomReference are probably better is superficially more complicated).
If you are looking for alternatives to finalize() the proper question would be:
Why use an explicit close() method like, for example, all the stream and writer/reader classes in java.io.* and many others - when there is finalize()?
The other answers make it clear that the disadvantage of finalize() is that you have no way to force it to run, and neither do any who might use your code.
Of course, calling a close() methode (best done in a finally block or in a close() method itself) has to be documented by the author and then remembered to be called by the ones using the code. But there are lots of examples (not only java.io.*) where this is imposed and it works.
BTW: close() is merely a convention.
Joshua Bloch makes a very clear recommendation in his book Effective Java (2nd Edition). Copied from chapter 2 Item 7: Avoid finalizers:
Finalizers are unpredictable, often dangerous, and generally unnecessary. Their use can cause erratic behavior, poor performance, and portability problems. Finalizers have a few valid uses, which we’ll cover later in this item, but as a rule of thumb, you should avoid finalizers.
Please read the reference to find out why.

flush in java.io.FileWriter

I have a question in my mind that, while writing into the file, before closing is done, should we include flush()??. If so what it will do exactly? dont streams auto flush??
EDIT:
So flush what it actually do?
Writers and streams usually buffer some of your output data in memory and try to write it in bigger blocks at a time. flushing will cause an immediate write to disk from the buffer, so if the program crashes that data won't be lost. Of course there's no guarantee, as the disk may not physically write the data immediately, so it could still be lost. But then it wouldn't be the Java program's fault :)
PrintWriters auto-flush (by default) when you write an end-of-line, and of course streams and buffers flush when you close them. Other than that, there's flushing only when the buffer is full.
I would highly recommend to call flush before close. Basically it writes remaining bufferized data into file.
If you call flush explicitly you may be sure that any IOException coming out of close is really catastrophic and related to releasing system resources.
When you flush yourself, you can handle its IOException in the same way as you handle your data write exceptions.
You don't need to do a flush because close() will do it for you.
From the javadoc:
"Close the stream, flushing it first. Once a stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously-closed stream, however, has no effect."
To answer your question as to what flush actually does, it makes sure that anything you have written to the stream - a file in your case - does actually get written to the file there and then.
Java can perform buffering which means that it will hold onto data written in memory until it has a certain amount, and then write it all to the file in one go which is more efficient. The downside of this is that the file is not necessarily up-to-date at any given time. Flush is a way of saying "make the file up-to-date.
Close calls flush first to ensure that after closing the file has what you would expect to see in it, hence as others have pointed out, no need to flush before closing.
Close automatically flushes. You don't need to call it.
There's no point in calling flush() just before a close(), as others have said. The time to use flush() is if you are keeping the file open but want to ensure that previous writes have been fully completed.
As said, you don't usually need to flush.
It only makes sense if, for some reason, you want another process to see the complete contents of a file you're working with, without closing it. For example, it could be used for a file that is concurrently modified by multiple processes, although with a LOT of care :-)
FileWriter is an evil class as it picks up whatever character set happens to be there, rather than taking an explicit charset. Even if you do want the default, be explicit about it.
The usual solution is OutputStreamWriter and FileOutputStream. It is possible for the decorator to throw an exception. Therefore you need to be able to close the stream even if the writer was never constructed. If you are going to do that, you only need to flush the writer (in the happy case) and always close the stream. (Just to be confusing, some decorators, for instance for handling zips, have resources that do require closing.)
Another usecase for flushing in program is writing progress of longrunning job into file (so it can be stopped and restarted later. You want to be sure that data is safe on the drive.
while (true) {
computeStuff();
progresss += 1;
out.write(String.format("%d", progress));
out.flush();
}
out.close();

Categories