I frequently output text to files. I wonder something: how does BufferedWriter
work?
Does it write text on file when I call writer.write(text)
?
If it doesn't write text,do I need to use flush function to write data?
For example:
File file = new File("statistics.txt");
if (!file.exists()) {
file.createNewFile();
}
else
{
file.delete();
file.createNewFile();
}
FileWriter fileWritter = new FileWriter(file.getAbsoluteFile(),true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
Iterator<Map.Entry<String,Token>> it = listofTakenPairMap.entrySet().iterator();
int isim_isim=0;
int isim_fiil=0;
int zarf_fiil=0;
while (it.hasNext()) {
@SuppressWarnings("rawtypes")
Map.Entry pairs = (Map.Entry)it.next();
Token token=(Token)pairs.getValue();
String str=pairs.getKey()+ " = " +token.getCount();
if(token.getTypeOfPairofToken()==0){//isim-isim
isim_isim+=token.getCount();
}
else if(token.getTypeOfPairofToken()==1){
isim_fiil+=token.getCount();
}
else{ //zarf-fiil
zarf_fiil+=token.getCount();
}
System.out.println(str);
bufferWritter.write(str);
bufferWritter.newLine();
//it.remove(); // avoids a ConcurrentModificationException
}
bufferWritter.newLine();
bufferWritter.write("##############################");
bufferWritter.newLine();
bufferWritter.write("$isim_isim sayisi :"+isim_isim+"$");
bufferWritter.newLine();
bufferWritter.write("$isim_fiil sayisi :"+isim_fiil+"$");
bufferWritter.newLine();
bufferWritter.write("$zarf_fiil sayisi :"+zarf_fiil+"$");
bufferWritter.newLine();
bufferWritter.write("##############################");
bufferWritter.flush();
bufferWritter.close();
If an error occurs in the while loop,the file will be closed without writing data. If I use flush
function in the while loop,then why should i use BufferedWriter
? Please correct me If I'm wrong.
Check the jdk's source code youself
No. Whenever you call
write(String s)
, you will call:write(str, 0, str.length());
This is the source code from the source of openJDK:As you see, it will not write directly. Only when
if (nextChar >= nChars)
, it will flush the buffer itself (default isprivate static int defaultCharBufferSize = 8192;
by using its "wrapping" class. (In java, Java IO is design using Decorator Design Pattern. In the end, it will call thewrite(char[] chars, int i, int i1)
. )IO cost is VERY expensive. Unless you need to view the output "on-the-fly" (Eg view the log any time with the newest update), you should let the be done automatically the increase the performance.
By definition, a buffered writer buffers data and only writes them when it has enough in memory, to avoid too many roundtrips to the file system.
If you handle exceptions properly, and close your stream in a finally block as you should always do, the buffer will be flushed to the disk, and everything written to the buffered writer so far will be written to the disk (unless of course the exception is precisely caused by an error writing to the disk).
So, the solution is not to flush each time ou write, since it would defeat the purpose of the buffered writer. The solution is to close in a finally block (or to use the Java 7 trye-with-resources statement, which does that for you).
Data in the streams are written to the disk in blocks. So, when you write something into your
OutputStream
orWriter
, you should not expect that the server automatically persist to the disk - this is actually done very rarely. Your process is just a small process in the Virtual Machine and in the host operating system.If you write the data to the disk, you have to wait for the Disk I/O to finish. Your code is not executed during that time, but waiting. This will increase the service time.
Also, frequent disk write (mean
flush()
) will put heavy load on the system, because it cannot simply overwrite the full content of the block, but rather has to update the same block many times.So, that's why languages like Java introduced the buffering.
To answer your question: When you
write()
data, it will be buffered to a certain level (until the buffer is full). After that it will be persisted (written to the underlyingStream
, e.g.FileOutputStream
). When you call aflush()
orclose()
, it will empty the buffer, so all bytes that were buffered will be written to the underlyingStream
. They also call theflush()
orclose()
method of that Stream.If an
Exception
happens in the loop, you will not close the stream, so some data may be lost. Surround withtry { } catch (IOException ex) {}
and close the stream properly.