How does BufferedWriter work in java

2019-06-19 07:38发布

I frequently output text to files. I wonder something: how does BufferedWriterwork?

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.

3条回答
我想做一个坏孩纸
2楼-- · 2019-06-19 08:24

I frequently output text to files. I wonder something: how does BufferedWriter work?

Check the jdk's source code youself

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?

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:

  218     public void write(String s, int off, int len) throws IOException {
  219         synchronized (lock) {
  220             ensureOpen();
  221 
  222             int b = off, t = off + len;
  223             while (b < t) {
  224                 int d = min(nChars - nextChar, t - b);
  225                 s.getChars(b, b + d, cb, nextChar);
  226                 b += d;
  227                 nextChar += d;
  228                 if (nextChar >= nChars)
  229                     flushBuffer();
  230             }
  231         }
  232     }
  233      


  118     /**
  119      * Flushes the output buffer to the underlying character stream, without
  120      * flushing the stream itself.  This method is non-private only so that it
  121      * may be invoked by PrintStream.
  122      */
  123     void flushBuffer() throws IOException {
  124         synchronized (lock) {
  125             ensureOpen();
  126             if (nextChar == 0)
  127                 return;
  128             out.write(cb, 0, nextChar);
  129             nextChar = 0;
  130         }
  131     }    

As you see, it will not write directly. Only when if (nextChar >= nChars), it will flush the buffer itself (default is private 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 the write(char[] chars, int i, int i1). )

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?

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.

查看更多
相关推荐>>
3楼-- · 2019-06-19 08:34

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).

查看更多
劳资没心,怎么记你
4楼-- · 2019-06-19 08:35

Data in the streams are written to the disk in blocks. So, when you write something into your OutputStream or Writer, 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 underlying Stream, e.g. FileOutputStream). When you call a flush() or close(), it will empty the buffer, so all bytes that were buffered will be written to the underlying Stream. They also call the flush() or close() method of that Stream.

If an Exception happens in the loop, you will not close the stream, so some data may be lost. Surround with try { } catch (IOException ex) {} and close the stream properly.

查看更多
登录 后发表回答