4

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?

  • Instead of creating a byte[], it would be more efficient to write the data directly to the OutputStream. – Peter Lawrey Apr 16 '13 at 12:00
  • Btw, I estimate if you do not work on a mission-critical non-db solution that must be able to recover to a well-defined state after powering down the PC in the middle of something, you can survive *centuries* in the IT world without flushing anything, ever. And even there the flush method is rather small part of the game. I.e. it is a very specialized weapon you are aming with, and I doubt you have a suitable target. – TheBlastOne Apr 16 '13 at 15:00

2 Answers2

1

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

Community
  • 1
  • 1
  • +1 flush() might be needed if your don't want to close the stream. – Peter Lawrey Apr 16 '13 at 11:59
  • yes I know.but thats y i pointed out that i commented flush and close methods in my program and still it can write in to the file..then why flush is exactly needed? – user2286271 Apr 16 '13 at 12:00
  • flush is designed to flush all buffers, i.e. when you call flush, then upon return, in theory, you can power off the machine without loosing data. Or let´s say: Leaving the hd contents in exactly the state that results from writing all outstanding writes out. – TheBlastOne Apr 16 '13 at 12:06
  • So flush just makes sure (or at least tries to make sure) that all write buffers are written to disk (flushed). For example, without a flush, a target file might be 0 bytes long even though you wrote 10 bytes. Call flush, and the file should be 10 bytes in size, with the correct 10 bytes written to disk. – TheBlastOne Apr 16 '13 at 12:08
  • @TheBlastOne Please don't forget, that the flush only guarantee that the data will be send from any Java buffers to the operating system. It is still possible, that if you power off the machine you will lose the data that was in the system buffer or HDD buffer. You would use 'RandomAccessFile' in 'rws' mode to ensure that bytes are written. Another example of using flush is for saving log information - you don't want to close the file, but you want to have the information saved in case of an exception, while at the same time you don't care about log if the failure was caused by power off. – user2281279 Apr 16 '13 at 12:15
  • but even with out calling flush my file is getting updated only with write() method?and file stream doesnot uses memory or buffer then why we need flush(which checks the buffer)? – user2286271 Apr 16 '13 at 12:16
  • @user2286271 Correct, if you are using a stream without any buffer, then calling write will do the same as calling flush after every write. Flush is needed for some streams, but we have it for all streams to keep things simple. BTW. you shouldn't worry about memory usage by buffered streams - you can easily afford having 10KB buffer, while I/O operations are expensive. – user2281279 Apr 16 '13 at 12:27
  • @TheBlastOne but even with out calling flush my file is getting updated only with write() method?and file stream doesnot uses memory or buffer then why we need flush(which checks the buffer)? – user2286271 Apr 16 '13 at 12:28
  • Regarding "Why does it flush if I don´t" -- PCs are very fast thesedays, you seldomly see non-empty write buffers. You will want flush only for the really critical moments when you want everything to be written NOW. And yes there still are buffered writes that you cannot see -- internal buffers in the runtime system, or the OS. – TheBlastOne Apr 16 '13 at 14:50
  • Regarding the "Flush guarantees only flushing to the OS" yes, unfortunately. Many other runtimes (Delphi, C) "flushthrough" to the OS so the OS flushes all buffers, too. I´d suspect most Java VM implementations will do so, too. – TheBlastOne Apr 16 '13 at 14:52
  • Regarding the "You can still loose data because of HDD controller write buffers" -- well if things die in the middle of a low-level write operation, yes. But still the OS might define a driver I/O interface for flushing, and good driver implementation will "flushthrough" this way. But if the flush command "chain" from Java to OS to driver to controller is well-implemented, flush won´t return in this case because the system died. And flush does not say "I flush everything!", it says "When I return, everything will be flushed". If not, well.... :-O – TheBlastOne Apr 16 '13 at 14:55
0

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.

Carlo Pellegrini
  • 5,281
  • 38
  • 41
  • "In fact, FileOutputStream is not buffered, so the data is directly written to the file" means we dont need flush in this case of file output stream? – user2286271 Apr 16 '13 at 12:17
  • do we need flush in the fileoutputstream ? – user2286271 Apr 16 '13 at 12:26
  • No. Close implies a flush. – TheBlastOne Apr 16 '13 at 14:56
  • @user2286271 Yes, there is no need (but is still a best practice) (BTW: `close()` does NOT imply `flush()`, only subclasses of `FilterOutputStream` - not overriding `close()` - inherit the flush at close behaviour. You stumble on this strangeness when you work with sockets...) – Carlo Pellegrini Apr 16 '13 at 15:07
  • I am trying to understand piped streams. Instead of piped stream why cant we use other streams to pipe each other?like below final ByteArrayOutputStream pos = new ByteArrayOutputStream(); final ByteArrayInputStream pis = new ByteArrayInputStream(pos.toByteArray()); and when we will have dead lock in piped stream?i tried to read and write using single main thread..it executes smoothly? – user2286271 Apr 17 '13 at 13:32