5

我理解背后的理论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

4 回答 4

2

当数据被刷新时,它是一个块。

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       }
于 2012-02-14T19:37:15.720 回答
1

从您的链接:

   /** 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)and void write(int b)(类中的核心方法,每次写入都被委托给它),以便它写入缓冲区,并在必要时刷新。

于 2012-02-14T19:35:47.777 回答
0

代码指出:

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       }

这是对所有当前缓冲字节的写入。不是逐字节的。

于 2012-02-14T19:36:07.103 回答
0

这个想法是用户BufferedOutputStream不必等待每个字节都被真正发送。即使连接本身很慢,用户也可以将更大的块推送到输出流并继续。所以这边比较快。输出流本身试图尽可能快。

于 2012-02-14T19:36:31.483 回答