BufferedOutputStream如何实际工作在较低水平?

我理解BufferedOutputStream背后的理论。 字节被写入缓冲区数组直到它已满,然后写入(刷新)到底层流 – 这个想法是它比逐字节写入更快,因为OS调用更少。

但是,从查看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循环逐字节写入

请有人澄清实际发生的事情,以及它如何更快?

刷新数据时,它就像一个块。

 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 len bytes from the specified byte array 310 * starting at offset off 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 } 

从您的链接:

  /** 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) (每个写入的类中的核心方法),以便它写入缓冲区,必要时刷新。

代码说明:

 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 } 

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

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