Petro Petro - 7 months ago 9
Java Question

Calling close() on OutputStream is cutting off output to a log file

I was looking into a problem with

.close()
causing cut-off issues. The program is running on two different servers, but had the same cutoff issue. It appears that the log file is not flushing properly. So I decided to dig into the
.close()
source code. I don't see a
.flush()
being called. Am I missing something? Should we always call
.flush()
? According to this answer, it shouldn't matter: Using flush() before close()

What I'm calling:

private static void write_to_file(String incoming){
output_stream.write(incoming);
output_stream.write(System.lineSeparator());
}


Later on I call
output_stream.close();


The source code:

/**
* Closes the stream and releases any system resources associated
* with it. Closing a previously closed stream has no effect.
*
* @see #checkError()
*/
public void close() {
try {
synchronized (lock) {
if (out == null)
return;
out.close();
out = null;
}
}
catch (IOException x) {
trouble = true;
}
}


Log file:


C:\apps\bot\log\processed\file.0000090.gz
C:\apps\bot\log\processed\file.0000091.gz
C:\apps\bot\log\process


Answer

As stated in the question you've correctly pointed out, calling close() on a stream is enough to flush whatever you've written to the stream. If the output is truncated, there are a few common pitfalls:

  • Your close() method is not called, e.g. if you put it in a catch block instead of finally ;)

  • Calling close() on a custom stream doesn't propagate the call to the underlying stream.

  • The problem can also be in encoding if you don't properly convert your String to bytes.

Comments