How does BufferedWriter work in java

孤人 提交于 2019-12-23 09:17:29

问题


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.


回答1:


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




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/14462705/how-does-bufferedwriter-work-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!