views:

226

answers:

1

I have one method that opens a file and passes off to another function to write some data to it. That second method wants to use PrintWriter to write its data. However, I didn't want to require that everybody use PrintWriter to write to that stream.

Currently it looks something like this ( sanitized example... don't bother criticizing my choice of method or variable names )

public void exportRawDataIntoStream(OutputStream os) {
    PrintWriter pr = new PrintWriter(os);
    printFirstData(pr);
    printSecondData(pr);
}

public void exportToFile(File file) {
    OutputStream os = null;
    try {
     os = new BufferedOutputStream(new FileOutputStream(file));
     exportRawDataIntoStream(os);
                doMoreWithTimeFile(os);
    } finally {
     if (os != null) {
      try {
       os.close();
      } catch (Exception e ) {
       e.printStackTrace();
      }
     }
    }
}

This doesn't work, unless I put a 'pr.flush' at the end of exportRawDataIntoStream. I can't close the PrintWriter, because that closes the whole stream.

Is doing the flush legitimate and reliable? Is there some other approach I should use to mix Writers on the same stream, or should I just absolutely never do that?

+1  A: 

Yes, flush should be reliable. It's basic role is to "push along" any excess data.

However, to be fair, that will only work with your basic Writers. Mind, I think that is most, if not all, of them.

But consider some contrived special kind of writer. Something that "does something else" on close. Like an encryption or compression stream.

Say, you had a "base64 encoder writer", it can't safely write the potentially trailing "==" until it is DONE, and that's a close, not a flush.

But with that caveat, for your case with the PrintWriter, it shouldn't be a problem.

Will Hartung
Also note that implementations of Writers and OutputStreams which wrap other streams vary on whether close() actually closes the underlying stream. In some cases, you may be able to invoke close() if you know that the underlying stream will not be closed.
JimN
Things like compression streams typically have a finish() method or similar to handle finishing the output without closing the underlying stream.
Software Monkey
Yea, that's always been a point of confusion. It's my understanding that "close" is supposed to close the entire chain, but, as you say, some do, some don't.
Will Hartung