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?
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
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.
From the Java API specification:
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.
Write text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings.
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.
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;
).
Source: Stackoverflow.com