如何在不关闭流的前提下反复读取文件数据

在创建一个流的时候,就比如说FileIntputStream,我们在读取文件信息的时候,文件的指针会随着文件的读取从文件头一直往文件尾移动,当我们把文件中的数据都读完了,文件的指针也就到达了文件尾部,你若是再使用这个流去读取文件,显然你已经无法在读取前面的信息了。

如下图所示

下面是打印信息,显然没有进入第二个循环中,只打印了一个空行

 

 

当然如果你在重新读取之前你把流关闭,这能将文件的指针重新指向文件头,这也就能重新读取文件的信息了。

如图所示

 

这显然是我们所期望的。

但是这并不能适用于任何情况,就比如说我们在使用Buffered和PrintWriter时,这两个流其实是包装流,也可以说是高级流,在他们被创建的时候,实际上会在底层创建一个原始流,就说是底层流吧,我们在关闭Buffered和PrintWriter时,也将会把底层流给关闭,若是底层正在进行数据的读与写操作,这很可能会将数据丢失, 显然如果我们把底层流关闭,也将会出异常,原始流都没有了,包装流还有什么用呢。

如下图所示

 

再考虑上面的,这种方法显然已经行不通了,这就需要我们去考虑其他路径了我们在使用BufferedInputStream是可以发现这个类里面的方法有一个是markSupported()这个方法决定是否这个类可以标记文件

我们看如下

 如果可以标记则就返回true,不能就返回false,上图三方法是需要调用的三方法,mark(int reaflimit)是标记文件的位置,里面的参数意思是:在标记位置变无效之前所能读的字节的最大极限,reset()方法可以在有效范围内回到文件的标记位置。

我们看下面的示例

 

 你会发现好神奇,竟然能打印出来,你会发现我给Mark()传的参数是21,而文件里的数据也是而是一个字节,这刚刚好,根据我上面的说明,这个reset()是可以返回文件指针的,但是当我将参数传为0是,这也能打印出来

如下图所示

 

 这又很神奇吧,好像这个readlimit参数没有任何用处,实际上并不完全对,事实上,mark 在 Java 中的实现是和缓冲区相关的。只要缓冲区够大,mark 后读取的数据没有超出缓冲区的大小,mark 标记就不会失效,但是如果缓存区域大小很小,当区域占满了数据,则缓存区域将会更新,这时候的缓存区域将会被重置,里面的mark也将会消失,因此,mark 后读取多少字节才失效,并不完全由 readlimit 参数确定,也和 BufferedInputStream 类的缓冲区大小有关,只有超过了缓冲区域的大小mark才会失效,甚至可以认为这只和缓存区域的大小有关,区域越大,我能反复读取文件的余地也就越大,反之区域越小,mark有效的区域也就越小。

在BufferedInputStream类中有两个成员属性,关于缓冲区域大小的,可供参考,如下图

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值