我理解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循环来逐字节写
请有人澄清实际发生了什么,以及它是如何更快的?
答案 0 :(得分: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 }
答案 1 :(得分: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)
和void write(int b)
(每个写入委托的类中的核心方法),以便它写入缓冲区,在必要时刷新。
答案 2 :(得分: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 }
这是对所有当前缓冲字节的写入。不是逐字节的。
答案 3 :(得分:0)
我们的想法是BufferedOutputStream
的用户不必等待真正发送的每个字节。即使连接本身很慢,用户也可以将更大的块推送到输出流并继续。所以这方面更快。输出流本身试图尽可能快。