Как BufferedOutputStream на самом деле работает на низком уровне? - PullRequest
5 голосов
/ 14 февраля 2012

Я понимаю теорию, стоящую за BufferedOutputStream.Байты записываются в буферный массив до тех пор, пока он не будет заполнен, а затем записываются (сбрасываются) в базовый поток - идея состоит в том, что это быстрее, чем запись побайтно, так как меньше вызовов ОС.

Однако, глядя на реализацию класса и методов BufferedOutputStream ( BufferedOutputStream.java ), кажется, что в конечном итоге байты из буфера просто записываются побайтово.

Я думаю, что это так, потому что:

В BufferedOutputStream.write (byte b [], int off, int len) у него есть строка out.write (b, off, len).Поскольку out является экземпляром OutputStream, но не BufferedOutputStream, он вызывает OutputStream.write (byte [], int, int).Это, в свою очередь, использует цикл for для записи побайтно

Пожалуйста, кто-нибудь может уточнить, что на самом деле происходит и как это быстрее?

Ответы [ 4 ]

2 голосов
/ 14 февраля 2012

Когда данные сбрасываются, это как блок.

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 и многие другие переопределяют OutputStream.write () для эффективной обработки блоков данных.

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       }
1 голос
/ 14 февраля 2012

По вашей ссылке:

   /** 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();
   }

Как видите, flush() записывает все содержимое буфера за один раз в нижележащий поток, а затем осуществляет каскадную очистку. BufferedOutputStream затем переопределяет write(byte b[], int off, int len) и void write(int b) (основные методы в классе, которому делегирована каждая запись), чтобы он записывал в буфер, сбрасывая при необходимости.

0 голосов
/ 14 февраля 2012

Идея состоит в том, что пользователь из BufferedOutputStream не должен ждать, чтобы каждый байт был действительно отправлен. Пользователь может просто вставить больший блок в выходной поток и продолжить, даже если само соединение медленное. Так что быстрее на этой стороне. Сам выходной поток пытается быть максимально быстрым.

0 голосов
/ 14 февраля 2012

Код гласит:

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       }

Это запись всех буферизированных байтов.Не побайтово.

...