Search code examples
javaiobufferfilereaderfilewriter

How is there no flush in FileReader, but there is for FileWriter?


Say I try to run this code:

FileWriter fw = new FileWriter("a.txt");
fw.write("A");

It wouldn't work as data is buffered and won't be auto flushed until it reaches max buffer size. So we flush manually with fw.flush();, after which this would work.

Then I want to read data from the same file. I do this and it works fine:

FileReader fr = new FileReader ("a.txt");
System.out.println (fr.read ());
OUTPUT: 65

Can someone tell me why is there no method flush() for fileReader as well? I mean shouldn't it work the same as fileWriter just the opposite? Instead of buffering data before being sent to the source, in this case, data would be buffered before being read. I am afraid I am missing something elementary, can someone please point it out?


Solution

  • In the case of an output stream/FileWriter, the data you write to it is buffered before actually being written to the file. This means that it is not actually written to the file until enough data has been accumulated in a buffer, so as to reduce the number of writes to the file. Therefore you need to flush it to "force" it to write the "A". You want the "A" to be written.

    But it makes no sense to "flush" an input stream/FileReader (whatever that means). An input stream buffers its data too. This means that when you read, it reads more data than you need, puts them in a buffer, so that when you call read again, it can just read from the buffer, rather than from the file (until the buffer runs out, of course). See also this question about flushing.

    Unlike the buffered-but-unwritten data in an output stream (which you really want written), you don't actually care about the buffered-but-unread data in an input stream. This is kind of by definition - it's unread. If you really care about it, you would have read it.


    Here's an analogy about washing clothes: Imagine ClothesReader and ClothesWriter are clothes-washing robots that help put your dirty clothes into the wash and give it back to you respectively. They both have little baskets (buffers) that they carry around.

    You can put your dirty clothes into ClothesWriter's basket. It won't take it to the washing machine immediately though, because washing just one piece of clothing at a time is generally inefficient. It will wait patiently until the basket is full, and then put its contents into the washing machine. However, what if you have something that needs to be washed immediately? There needs to be a button on the robot that says "put the basket contents into the washing machine now". And that button is flush.

    After the washing machine has done its thing, you can request clean clothes from ClothesReader. Since it is inefficient to go to the washing machine then back to you every time you request something, whenever its basket is empty, it fills up its basket with clothes from the washing machine. This way, when you request something, it can just take it out from its basket and give it to you, which is very fast compared to going to the washing machine and back.

    You wouldn't want a "give me all the stuff in your basket" button on a ClothesReader, which (I guess?) is what FileReader.flush would do if it existed, because it would not be useful. You don't know what clothes are left in its basket, or how many there are.