概述

该类是缓冲输出流的实现。通过设置这样的一个输出流,可以避免每写入一个字节都产生一次底层系统调用。

write(byte b[], int off, int len)方法

从目标字节数组b的给定下标位置offset开始,写入len个字节到缓冲输出流中。

该方法实现如下:

路径一:如果len >= buf.length,则将缓冲区的内容全部写入到底层输出流,清空缓冲区。然后再将目标字节数组的内容直接写入到底层输出流,这样能实现缓冲输出流的优雅降级。

路径二:在路径一不满足的基础上,如果len > buf.length - count,则将缓冲区的内容全部写入到底层输出流,清空缓冲区,然后再将目标字节数组的内容复制到缓冲区。

路径三:如果路径一和二都不满足,即len <= buf.length - count,缓冲区的可用空间大于写入字节数,直接将目标字节数组的内容复制到缓冲区。

flush方法

flush方法将缓冲区的内容全部写入到底层输出流,清空缓冲区。

flush()方法可以强迫输出流(或缓冲的流)发送数据,即使此时缓冲区还没有填满。

当我们使用输出流发送数据时,当数据不能填满输出流的缓冲区时,这时,数据就会被存储在输出流的缓冲区中。如果,我们这个时候调用关闭(close)输出流,存储在输出流的缓冲区中的数据就会丢失。所以说,关闭(close)输出流时,应先刷新(flush)换冲的输出流,话句话说就是:“迫使所有缓冲的输出数据被写出到底层输出流中”。

flush()其实是Flushable接口的方法

/*** A <tt>Flushable</tt> is a destination of data that can be flushed.  The* flush method is invoked to write any buffered output to the underlying* stream.** @since 1.5*/
public interface Flushable {/*** Flushes this stream by writing any buffered output to the underlying* stream.** @throws IOException If an I/O error occurs*/void flush() throws IOException;
}

所有的输出流都实现了这个接口。因为OutputStream实现了Flush接口,而其它的输出流都继承自OutputStream。

但在OutputStream的flush方法里,什么也不做。而除了BufferedOutputStream重写了flush方法并做了强制缓冲区的内容写入到底层输出流的有效操作外,其它输出流要么没有重写flush方法,要么在重写的flush方法里,只是简单调用了被装饰的输出流的flush方法。

举个例子,调用FileOutputStream的flush方法完全没有必要,因为它会调用父类OutputStream的flush方法,而这个方法什么也不做。

什么时候flush方法是有效的?

只有当输出流是BufferedOutputStream,或者输出流装饰了BufferedOutputStream,调用它的flush方法才是有效的。

BufferedoutputStream的源码如下:

/*** The class implements a buffered output stream. By setting up such* an output stream, an application can write bytes to the underlying* output stream without necessarily causing a call to the underlying* system for each byte written.** @author  Arthur van Hoff* @since   JDK1.0*/
public class BufferedOutputStream extends FilterOutputStream {/*** The internal buffer where data is stored.存储数据的内部buffer*/protected byte buf[];/*** The number of valid bytes in the buffer. This value is always* in the range <tt>0</tt> through <tt>buf.length</tt>; elements* <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid* byte data.在buffer中有效字节的数量*/protected int count;/*** Creates a new buffered output stream to write data to the* specified underlying output stream.** @param   out   the underlying output stream.*/public BufferedOutputStream(OutputStream out) {this(out, 8192);}/*** Creates a new buffered output stream to write data to the* specified underlying output stream with the specified buffer* size.** @param   out    the underlying output stream.* @param   size   the buffer size.* @exception IllegalArgumentException if size &lt;= 0.*/public BufferedOutputStream(OutputStream out, int size) {super(out);if (size <= 0) {throw new IllegalArgumentException("Buffer size <= 0");}buf = new byte[size];}/** Flush the internal buffer *///将缓冲区的内容全部写入到底层输出流,清空缓冲区private void flushBuffer() throws IOException {if (count > 0) {out.write(buf, 0, count);count = 0;}}/*** Writes the specified byte to this buffered output stream.** @param      b   the byte to be written.* @exception  IOException  if an I/O error occurs.*/public synchronized void write(int b) throws IOException {if (count >= buf.length) {flushBuffer();}buf[count++] = (byte)b;}/*** Writes <code>len</code> bytes from the specified byte array* starting at offset <code>off</code> to this buffered output stream.** <p> Ordinarily this method stores bytes from the given array into this* stream's buffer, flushing the buffer to the underlying output stream as* needed.  If the requested length is at least as large as this stream's* buffer, however, then this method will flush the buffer and write the* bytes directly to the underlying output stream.  Thus redundant* <code>BufferedOutputStream</code>s will not copy data unnecessarily.** @param      b     the data.* @param      off   the start offset in the data.* @param      len   the number of bytes to write.* @exception  IOException  if an I/O error occurs.*/public synchronized void write(byte b[], int off, int len) throws IOException {if (len >= buf.length) {/* If the request length exceeds the size of the output buffer,flush the output buffer and then write the data directly.In this way buffered streams will cascade harmlessly. */flushBuffer();out.write(b, off, len);return;}if (len > buf.length - count) {flushBuffer();}//将目标字节数组的内容复制到缓冲区System.arraycopy(b, off, buf, count, len);count += len;}/*** 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();}
}

参考:揭开Java IO流中的flush()的神秘面纱

BufferedOutputStream源码分析与flush方法相关推荐

  1. Android源码分析工具及方法

    转载自:http://bbs.pediy.com/showthread.php?t=183278 标 题: [原创]Android源码分析工具及方法 作 者: MindMac 时 间: 2014-01 ...

  2. jquery1.43源码分析之工具方法

    相关文章: jQuery插件开发全解析 读jq之四 jquery1.43源码分析之核心部分 推荐圈子: Jquery 更多相关推荐 这个部分是jquery一些常用的工具方法. 包括为jquery对象扩 ...

  3. Thread源码分析之join方法

    2019独角兽企业重金招聘Python工程师标准>>> join方法示例1 源码 import java.util.concurrent.TimeUnit;public class ...

  4. 案例:演示pageContext对象的使用及源码分析获取属性方法

    一.创建pageContext.jsp <%@ page language="java" contentType="text/html; charset=UTF-8 ...

  5. jQuery源码分析之$.ajax方法

    请阅读我其它的关于inspectPrefiltersOrTransport以及ajaxTransport等相关博文,请了解readyState状态码 针对获取到location.href的兼容代码: ...

  6. html2canvas实现浏览器截图的原理(包含源码分析的通用方法)

    DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师. 官方网站:devui.design Ng组件库:ng-devui(欢 ...

  7. 【Java源码分析】String 方法 startsWith

    startsWith() startsWith() 方法用于检测字符串是否以指定的前缀开始. 语法 public boolean startsWith(String prefix, int toffs ...

  8. JDK源码分析:hashCode()方法

    提问: 1.hashCode()源码是怎么实现的. 2.hashCode()是为了配合基于散列的集合而设计的 3.hash数据结构,如何做到存取的时间复杂度为O(1)的.{函数算>逐个比较} 答 ...

  9. 深入java并发包源码(三)AQS独占方法源码分析

    深入java并发包源码(一)简介 深入java并发包源码(二)AQS的介绍与使用 深入java并发包源码(三)AQS独占方法源码分析 AQS 的实现原理 学完用 AQS 自定义一个锁以后,我们可以来看 ...

  10. DialogFragment源码分析

    2019独角兽企业重金招聘Python工程师标准>>> 目录介绍 1.最简单的使用方法 1.1 官方建议 1.2 最简单的使用方法 1.3 DialogFragment做屏幕适配 2 ...

最新文章

  1. 单机塔防游戏推荐_电脑高自由度单机游戏推荐
  2. 测试硬盘读写速度软件_Linux 测试 IO 性能(磁盘读写速度)
  3. JAVA mysql存数组_JAVA数组怎么存放数据库的元素
  4. MATLAB递归程序的调试方法
  5. Ant in Action读书笔记(三):在Ant中导入环境变量
  6. ad电阻原理图_【雕爷学编程】Arduino动手做(2)---光敏电阻模块
  7. html网页表单设计实验报告,Html设计实验报告.doc
  8. 数据库系统概论第五版课后习题答案王珊
  9. 添加内核驱动模块(4)(mydriver.c+ Konfig+Makefile )
  10. java导出ppt_POI之PPT导出最简单实例
  11. bzoj4173:数学
  12. 偶数c语言中怎么写,偶数怎么写
  13. Vertica的这些事(四)—— 关于vertica常用函数介绍(持续更新ing)
  14. bne 1b什么意思
  15. 从魔兽玩家到区块链领袖,V神是如何打造出区块链2.0代表的以太坊
  16. 分享大神的一些博文、视频、资料--持续更新
  17. Linux修改系统时间为东八区北京时间(上海时间)
  18. 前馈神经网络(FNN)
  19. 工程伦理学_笔记(复习用)
  20. 蓝桥杯 结果填空 猜生日

热门文章

  1. 优动漫PAINT上色小技巧——套索填充功能教程
  2. SVG defs元素
  3. MySQL 幻读被彻底解决了吗?
  4. DZ先生怪谈国标28181-2016之目录查询
  5. 不怕崩溃 Ghost令机房管理化繁为简
  6. Python文件(二):数据组织的维度,一维数据的表示、存储、处理
  7. 【电商吧 - 3】支付第一步,支付宝网页支付!
  8. Android关于创建涂鸦板过程中出现的小问题
  9. 施一公:如何提高专业英文文献阅读能力?
  10. 3位1体学习法(smart哥)