当前位置: 移动技术网 > IT编程>开发语言>Java > I/O---BufferedInputStream及相关类介绍

I/O---BufferedInputStream及相关类介绍

2019年03月22日  | 移动技术网IT编程  | 我要评论
关于BufferedInputStream 是java提供的具有缓存作用的字节输入流。与之对应的还有BufferedOutStream 和 BufferedRead 和BufferedWriter 这4个都是FilterOutStream的子类。该使用装饰者模式对基础的InputStream进行装饰 ...

关于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位(可是现在超出缓冲数组的位数没有元素啊? 没有不代表以后不能有)

             然后将之前标记的元素复制到新的缓存数组中。

最后尝试将缓冲数组中空着的位置放入从文件中读取的新数据。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网