Java difference between FileWriter and BufferedWriter
Asked Answered
C

6

82

What's the difference between those? I'm just learning Java ATM, but it seems like I can write to a file both ways i.e. (I didn't copy the try-catch block here.)

FileWriter file = new FileWriter("foo.txt");
file.write("foobar");
file.close();

and

FileWriter file = new FileWriter("foo.txt");
BufferedWriter bf = new BufferedWriter(file);
bf.write("foobar");
bf.close();

I understand the concept of buffering the data first, so does that mean the first example writes the characters one by one and the second first buffers it to the memory and writes it once?

Ctn answered 10/9, 2012 at 10:57 Comment(0)
A
92

BufferedWriter is more efficient if you

  • have multiple writes between flush/close
  • the writes are small compared with the buffer size.

In your example, you have only one write, so the BufferedWriter just add overhead you don't need.

so does that mean the first example writes the characters one by one and the second first buffers it to the memory and writes it once

In both cases, the string is written at once.

If you use just FileWriter your write(String) calls

 public void write(String str, int off, int len) 
        // some code
        str.getChars(off, (off + len), cbuf, 0);
        write(cbuf, 0, len);
 }

This makes one system call, per call to write(String).


Where BufferedWriter improves efficiency is in multiple small writes.

for(int i = 0; i < 100; i++) {
    writer.write("foorbar");
    writer.write(NEW_LINE);
}
writer.close();

Without a BufferedWriter this could make 200 (2 * 100) system calls and writes to disk which is inefficient. With a BufferedWriter, these can all be buffered together and as the default buffer size is 8192 characters this become just 1 system call to write.

Adulthood answered 10/9, 2012 at 11:5 Comment(3)
I have a question that when I am using FileWriter, after write returns , does java guarantee that the content is flush in disk OR just in pagecache which os will flush when needed?Cattycornered
@Jaskey if you use FIleWriter unbuffered, write() means the OS has a copy which should be written to disk eventually.Adulthood
Well, maybe that was the case 10 years ago, but at least in Java 11 FileWriter extends OutputStreamWriter, which uses a StreamEncoder, which in turn has an internal 8KB buffer of its own (for a different reason than the BufferedWriter, but it's still a buffer). So you will probably not be writing to disk as many times as you call write()Moussaka
N
8

You are right. Here is how write() method of BufferedWriter looks:

public void write(int c) throws IOException {
    synchronized (lock) {
        ensureOpen();
        if (nextChar >= nChars)
            flushBuffer();
        cb[nextChar++] = (char) c;
    }
}

As you can see it indeed checks whether the buffer is full (if (nextChar >= nChars)) and flushes the buffer. Then it adds new character to buffer (cb[nextChar++] = (char) c;).

Nihilism answered 10/9, 2012 at 11:1 Comment(0)
L
5

BufferedWriter is more efficient. It saves up small writes and writes in one larger chunk if memory serves me correctly. If you are doing lots of small writes then I would use BufferedWriter. Calling write calls to the OS which is slow so having as few writes as possible is usually desirable.

Limousine answered 10/9, 2012 at 11:0 Comment(0)
D
0

From the Java API specification:

FileWriter

Convenience class for writing character files. The constructors of this class assume that the default character encoding and the default byte-buffer size are acceptable.

BufferedWriter

Write text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings.

Daubery answered 10/9, 2012 at 11:4 Comment(0)
G
0

http://docs.oracle.com/javase/1.5.0/docs/api/java/io/BufferedWriter.html

In general, a Writer sends its output immediately to the underlying character or byte stream. Unless prompt output is required, it is advisable to wrap a BufferedWriter around any Writer whose write() operations may be costly, such as FileWriters and OutputStreamWriters. For example,

PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

will buffer the PrintWriter's output to the file. Without buffering, each invocation of a print() method would cause characters to be converted into bytes that would then be written immediately to the file, which can be very inefficient.

Genitals answered 10/9, 2012 at 11:5 Comment(0)
H
0

In unbuffered Input/Output(FileWriter, FileReader) read or write request is handled directly by the underlying OS. https://hajsoftutorial.com/java/wp-content/uploads/2018/04/Unbuffered.gif

This can make a program much less efficient, since each such request often triggers disk access, network activity, or some other operation that is relatively expensive. To reduce this kind of overhead, the Java platform implements buffered I/O streams. The BufferedReader and BufferedWriter classes provide internal character buffers. Text that’s written to a buffered writer is stored in the internal buffer and only written to the underlying writer when the buffer fills up or is flushed. https://hajsoftutorial.com/java/wp-content/uploads/2018/04/bufferedoutput.gif

More https://hajsoftutorial.com/java-bufferedwriter/

Hakon answered 11/5, 2018 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.