BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能;BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式。

BufferedInputStream在其内部维护一个字节数组作为缓冲区,而从底层(文件)流中读取数据的操作还是调用InputStream的方法完成。

下面通过一个例子来讲解Buffered的缓冲区原理机制

public class BufferedInputStreamDemo {public static void main(String[] args) throws Exception {try (InputStream ai = new ByteArrayInputStream("1234567890".getBytes());InputStream bis = new BufferedInputStream(ai, 4)) {System.out.println("Char : " + (char) bis.read());    //step:1System.out.println("Char : " + (char) bis.read());    //step:2bis.mark(3);                                          //step:3System.out.println("-------mark(3)----------");System.out.println("Char : " + (char) bis.read());    //step:4System.out.println("Char : " + (char) bis.read());    //step:5System.out.println("Char : " + (char) bis.read());    //step:6bis.reset();                                          //step:7System.out.println("-------reset()----------");int b;while ((b = bis.read()) != -1) {System.out.println("char : " + (char) b);}} catch (Exception e) {e.printStackTrace();}}
}

输出的结果为:

Char : 1
Char : 2
-------mark(3)----------
Char : 3
Char : 4
Char : 5
-------reset()----------
char : 3
char : 4
char : 5
char : 6
char : 7
char : 8
char : 9
char : 0

准备

构造一个BufferedInputStream对象,缓冲区的大小为4字节。从ByteArrayInputStream流中读取数据“1234567890”。

变量说明:

pos:是下一次待读取缓冲区的坐标
markpos:mark()标记的缓冲区坐标。默认markpos=-1。

step:1

* 操作:read()*

第一次读取数据,首先初始化一个4字节大小的缓冲区,然后调用内部的fill()方法填充缓冲区,填充完成后开始读取缓冲区中的第一个元素“1”。
程序通过i++操作读取完第一个数据后pos坐标就会指向下一个待读取的元素(这里指向第二个元素)。

数组坐标是从0开始的,所以读取完成第一个元素后,pos=1。

pos=1

step:2

操作:read()

读出元素“2”

pos=2

step:3

操作:mark (3)

执行mark(3)进行标记。这时markpos和pos坐标相同.

markpos=2
pos=2

step:4

* 操作:read()*

读出元素“3”

markpos=2
pos=3

step:5

* 操作:read()*

读出元素“4”

markpos=2
pos=4

step:6

* 操作:read()*

当读取pos=4时,超出缓冲区容量,这时,需要重新再从目标流中读取元素。因为在step:3时mark标记过元素,当reset的时候还需要读取(元素“3和4”)。这时,需要把mark后的元素也要保留到缓冲区中,mark之前的数据丢弃(元素“1和2”)。剩下的容量读取新元素(还可读取两个元素“5、和6”)。
标记过的元素“3”的坐标现在为0。所以markpos=0。

读出元素“5”

markpos=0
pos=4

step:7

* 操作:reset()*

reset()后把pos的坐标置为0,然后在读取的时候又可以读取到元素“3、4、5”

后续while循环操作


读取元素“3”、“4”、“5”时坐标的变化

后续while循环操作

读取元素“6”

markpos=0
pos=4

注意:这时如果执行reset操作,那么将可以读取之前的4个元素(mark(3)的时候指定的是可以读取3个元素)

后续while循环操作


缓冲区读完后,重新再读取一批数据,因为该缓冲区没有执行mark操作,此时设置markpos=-1。

最后一次读取

读取元素“0”

本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8    
点击这里快速进入简书

GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT

BufferedInputStream 缓冲区原理解析相关推荐

  1. python中f点flush是什么函数_Python文件操作及内置函数flush原理解析

    1.打开文件得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 示例文件 '你好呀' 我是于超 嗯 再见 文件操作基本流程 f=open('chenli',encoding='ut ...

  2. easy excel date 类型解析报错_ptarchiver原理解析

    pt-archiver原理解析 作为MySQL DBA,可以说应该没有不知道pt-archiver了,作为pt-toolkit套件中的重要成员,往往能够轻松帮助DBA解决数据归档的问题.例如线上一个流 ...

  3. 分布式缓存系统Redis原理解析

    Redis作为内存数据库已经广泛应用于大数据领域,已经成为分布式架构下的基础组件.本文主要介绍了Redis内部的实现原理包括IO模型.内存管理.数据持久化等以及三种集群架构,旨在了解其中的实现机制. ...

  4. 《ClickHouse原理解析与应用实践》读书笔记(7)

    开始学习<ClickHouse原理解析与应用实践>,写博客作读书笔记. 本文全部内容都来自于书中内容,个人提炼. 第9章: <ClickHouse原理解析与应用实践>读书笔记( ...

  5. Java中字符流(FileReader(read、close)、FileWriter(write、close)、字符(输入、输出)流原理解析)

    1.创建对象: 2.读取数据 3.释放资源(关流) 如何使用重载的read()方法呢? FileWriter: 在前面我们指导,字节输出流和字符输出流的本质区别是,字节输出流一次只能操作一个字节,如果 ...

  6. Elasticsearch大数据量写入调优和原理解析

    前言 千万.亿级别数据批量写入ES的调优和原理解析 Elasticsearch version (bin/elasticsearch --version): 7.8 Plugins installed ...

  7. 大规模分布式存储系统:原理解析与架构实战 (大数据技术丛书) - 电子书下载 -(百度网盘 高清版PDF格式)...

    大规模分布式存储系统:原理解析与架构实战 (大数据技术丛书)-杨传辉 在线阅读                   百度网盘下载(89hy) 书名:大规模分布式存储系统:原理解析与架构实战 (大数据技 ...

  8. 时序数据库-2-[IoTDB]的原理解析

    清华自研时间序列数据库Apache IoTDB原理解析 时序数据库 Apache-IoTDB 源码解析之前言(一) 时序数据库 Apache-IoTDB 源码解析之系统架构(二) 时序数据库 Apac ...

  9. react vr 原理解析

    react vr中文网:www.vr-react.com react vr qq群:481244084 示例源码 github:https://github.com/LiuC520/ReactVR/ ...

最新文章

  1. 超简单的话解释C#事件-源码示例
  2. ESFramework介绍之(16)―― Tcp数据自动发送器ITcpAutoSender
  3. thinkphp 如何调用百度echarts 数据报表插件
  4. python md5算法调用与hashlib模块
  5. 编译opencv错误解决:libavcodec.a(hevc_cabac.o): `ff_h264_cabac_tables' can not be used
  6. 不要随便参加业主群的赏月大赛
  7. 封装Selenium2Library
  8. View 的测量 MeasureSpec
  9. 摄影小白入门相机选择(个人出发)
  10. 0宽字符隐藏文本加密及原理
  11. pentaho mysql_pentaho移植到MySQL
  12. 大数据技术就在生活中: 登机牌、阅卷与 Map-Reduce(归约)
  13. 大数据分析技术应用领域有哪些
  14. 二次元风格好看的视频解析官网html源码
  15. “西游记之大圣归来”短评主题分析-Latent Dirichlet Allocation
  16. leetcode 714 买卖股票的最佳时机含手续费-动态规划(中等)
  17. I have the Dream
  18. C语言深度学习之嵌套循环例题(金字塔模型)
  19. 【Java】基础、Java 数据类型
  20. uniapp 流文件pdf_uniapp写入字节流文件bytes

热门文章

  1. 三十、Pyspider爬虫框架总结,爬取Scrapy文档
  2. SVM支持向量机(上)
  3. 原生js.ajax内存溢出,javascript - 代码点火器-如何使用jQuery向数据库提交ajax javascript对象 - 堆栈内存溢出...
  4. 深度学习开发者的AI Party来了!WAVE SUMMIT+2021与你相约双十二
  5. 直播 | ICML 2021论文解读:满足隐私保护要求的去中心化无监督域迁移范式
  6. RealFormer:把残差转移到Attention矩阵上面去
  7. 思而后言:用点赞数据来帮助对话生成模型
  8. 免费注册丨全国社会媒体处理大会(SMP 2020)召开,98场报告日程全公开
  9. RecSys 2019最佳论文:基于深度学习的推荐系统是否真的优于传统经典方法?
  10. 周志华《机器学习》西瓜书出全新视频课啦!