I/O---BufferedInputStream及相关类介绍
关于BufferedInputStream 是java提供的具有缓存作用的字节输入流。与之对应的还有BufferedOutStream 和 BufferedRead 和BufferedWriter
这4个都是FilterOutStream的子类。该使用装饰者模式对基础的InputStream进行装饰,并提供了缓存作用。
关于缓冲数组的作用
由于CPU、内存、硬盘三者的速率不匹配.我们知道,如果一个文件有10KB大小,我们使用byte[1024] 数组 每次读取1kb时,CPU需要进行10次的IO读取,CPU需要终端10次转而执行IO操作。
那么现在引入了BufferedInputStream后,由于这个类内置的缓冲字节数组byte[8192] 。所以当我们第一次调用read()方法时,这个类内部会调用fill()方法,将一次读取8192个字节到缓存数组中。那么我们后续再次调用read()方法时,会首先到缓冲数组中查找,如果数据已经加载到数组中了,那么我们就不需要执行IO中断到硬盘读取。从而提高了读取速率。
BufferedOutputStream同理, 当我们向IO设备(String 、byteArray、object、File)写入操作时, 数据会先写入到缓冲数组中。如果缓冲数组满了之后,才会刷新到实际的地方。
所以在我们文件写入结束后,一定要手动关闭这个BufferedOutputStream().close().或者手动调用flush();
关于重复读写的作用
下面聊聊关于mark(readlimit)和reset()方法
============================================================================
简而言之,就是调用mark的时候,到mark + readlimit 位置的元素的,都可以反复读/写
============================================================================
首先要明白,在BufferedInputStream中有几个变量
int count; 记录当前缓冲数组中的元素个数
int markpos = -1; 记录mark的标志位下标,默认为-1
int marklimit; 记录可以进行reset的范围 //=========
int pos; 当前输入流将要读取的字节下标
正常情况下
随着read()的每次调用,pos都会++ ,当pos>=count时,意味着目前的缓冲数组的数据都已经读完,所以需要清空缓存数组,再次注入新的输入到缓存数组中,然后pos变成0 ,count变成读入的字节数;
调用mark(readlimit)过程。只是记录,并不会进行其他操作
当调用mark(int readlimit)方法时,会将pos赋值给markpos。也就是说会用markpos变量记录当前的位置,
然后将传入参数readlimit赋值给marklimit。
调用reset()方法:
首先判断缓冲数组是否关闭,如果获取不到(已经关闭了),则抛出异常
进行判断,在reset()之前是否已经执行过mark(),如果没有,则直接抛出异常。
然后将Pos调整到markpos位置。
调用fill()方法
想要填充新的缓存数组,就要先处理mark问题
1.没有进行mark标记,则直接填充缓存数组
2.进行了mark标记
2.1 markpos的位置正常(markpos > 0):将markpos到数组尾部的所有元素重新复制到数组头部,
sz = pos - markpos,pos = sz; markpos = 0;
2.2 buffer.length >= marklimit :marklimit小于缓冲数组长度,则初始化 markpos = -1; pos = 0;
2.3 如果marklimit超过了 buffer.length
将新的缓冲数组扩容2倍,如果扩容后还无法容纳,则直接扩容到marklimit位(可是现在超出缓冲数组的位数没有元素啊? 没有不代表以后不能有)
然后将之前标记的元素复制到新的缓存数组中。
最后尝试将缓冲数组中空着的位置放入从文件中读取的新数据。
最新文章
- ASP.NET MVC 设置Area中 Controller 的方法 默认启动页
- 手机影音1--SplashActivity
- MVC – 5.MVC设计模式和.NetMVC框架
- Mycat配置文件rule.xml
- iOS-图片轮播-SDCycleSCrollView的使用
- [Android Studio] 使用本地 aar 文件
- lvM增减教程-转
- SQL开发利器SQL Prompt
- [Everyday Mathematic]20150217
- hibernate--query接口初步
- java中线程队列BlockingQueue的用法
- 线性存储结构-ArrayList、Vector
- UITextfield设置Placeholder颜色 控件 内边距、自适应高度
- Use StringBuilder instead of String as possible as you can.
- Host文件修改后无效的解决办法
- 3.java的hello word.继承.泛型.反射.配置项.数据库操作.lombok
- SpringCloud学习笔记(1)——Eureka
- Spring Boot实战之逐行释义HelloWorld
- 如何提高windows的性能
- SQL慢查询测试实践
热门文章
- 短视频SDK在广电系统的解决方案
- table鼠标滑过变颜色
- Oracle反向字符截取逗號分隔字符串
- 梦想CAD控件,用于浏览和编辑DWG文件,在脱离AUTOCAD的情况下独立运行,相当于简易CAD
- Java基础(十一)--Serializable和Externalizable接口实现序列化
- Perl字符集就是方括号(或称中括号)里一连串可能的字符,只匹配单一字符,该单一字符可以是字符集里的任何一个,“-”在字符集里有特殊含义:表示某个范围的字符。而字符集意外的连字符不具有特殊意义。
- Python tldextract模块
- [转载]C++、C#写的WebService相互调用
- python 列表生成式、lower()和upper()的使用
- java中mkdir()和mkdirs()区别