How does BufferedOutputStream actually work at a low level?

若如初见. 提交于 2019-12-19 07:54:16

问题


I understand the theory behind BufferedOutputStream. Bytes are written to a buffer array until it is full, and then written (flushed) to the underlying stream - the idea being that it is faster than writing byte-by-byte as there are fewer OS calls.

However, from looking at the implementation of the BufferedOutputStream class and methods (BufferedOutputStream.java), it seems that ultimately, the bytes from the buffer are just written byte-by-byte.

I think this is the case because:

In BufferedOutputStream.write(byte b[], int off, int len) it has the line out.write(b, off, len). Since out is an instance of OutputStream, but not BufferedOutputStream, it is calling OutputStream.write(byte[], int, int). This in turn uses a for loop to write byte-by-byte

Please could someone clarify what is actually going on, and how it is faster?


回答1:


When the data is flushed, it is as a block.

79       /** Flush the internal buffer */
80       private void flushBuffer() throws IOException {
81           if (count > 0) {
82               out.write(buf, 0, count);
83               count = 0;
84           }
85       }

FileOutputStream and many other override OutputStream.write() to handle blocks of data efficiently.

http://www.docjar.com/html/api/java/io/FileOutputStream.java.html

284   
285       /**
286        * Writes a sub array as a sequence of bytes.
287        * @param b the data to be written
288        * @param off the start offset in the data
289        * @param len the number of bytes that are written
290        * @param append {@code true} to first advance the position to the
291        *     end of file
292        * @exception IOException If an I/O error has occurred.
293        */
294       private native void writeBytes(byte b[], int off, int len, boolean append)
295           throws IOException;

308       /**
309        * Writes <code>len</code> bytes from the specified byte array
310        * starting at offset <code>off</code> to this file output stream.
311        *
312        * @param      b     the data.
313        * @param      off   the start offset in the data.
314        * @param      len   the number of bytes to write.
315        * @exception  IOException  if an I/O error occurs.
316        */
317       public void write(byte b[], int off, int len) throws IOException {
318           writeBytes(b, off, len, append);
319       }



回答2:


From your link:

   /** Flush the internal buffer */
   private void flushBuffer() throws IOException {
       if (count > 0) {
           out.write(buf, 0, count);
           count = 0;
       }
   }

...

   /**
    * Flushes this buffered output stream. This forces any buffered
    * output bytes to be written out to the underlying output stream.
    *
    * @exception  IOException  if an I/O error occurs.
    * @see        java.io.FilterOutputStream#out
    */
   public synchronized void flush() throws IOException {
       flushBuffer();
       out.flush();
   }

As you can see, the flush() writes all the buffer contents in one go to the underlying stream and then cascades the flushing. BufferedOutputStream then reimplements write(byte b[], int off, int len) and void write(int b) (the core methods in the class to which every write is delegated) so that it writes into the buffer, flushing when necessary.




回答3:


The code states:

79       /** Flush the internal buffer */
80       private void flushBuffer() throws IOException {
81           if (count > 0) {
82               out.write(buf, 0, count);
83               count = 0;
84           }
85       }

This is a write of all the currently buffered bytes. Not byte-by-byte.




回答4:


The idea is that the user of BufferedOutputStream does not have to wait for every byte to be really sent. The user just can push a larger block to the outputstream and continue, even if the connection itself is slow. So it is faster on this side. The outputstream itself tries to be as fast as possible.



来源:https://stackoverflow.com/questions/9282909/how-does-bufferedoutputstream-actually-work-at-a-low-level

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