[十三]JavaIO之PushBackInputStream

功能简介

PushBackInputStream是针对于输入的一种扩展功能

装饰器模式中的具体的装饰类,抽象的装饰器为FilterInputStream

PushBackInputStream的重点在于理解缓冲区的使用手段

流本身不支持回退功能,想要能够pushBack 显然必须能够缓存数据PushBackInputStream内部维护了一个字节数组

不要想当然的认为,类似BufferedInputStream,内部缓冲了一个数组,所有的数据都要经过这个缓冲区,然后对他做处理 他内部维护的缓冲区,仅仅保存pushBack的字节

还需要注意的是他的内部缓冲区是从后往前写入的,也就是下图中的,从右往左下标索引大的先写入一旦写满, 会抛出异常throw new IOException("Push back buffer is full");

推回一个字节由于是从最后开始,一旦pos等于0也就是到了最前面,就无处可放了所以抛出异常否则,就在前面写入一个

推回 指定字节数组b 从off偏移量开始的len个字节推回len个长度,既然是从后往前设置数据,那么pos的值就是可用 空间 的个数如果空间不够,抛出异常否则,pos直接向前移动到指定位置然后借助于System.arraycopy 将b 便宜量off开始拷贝到

是unread(byte[] b, int off, int len)的简化形式用于拷贝整个数组

从unread可以清晰的看出来内部的缓冲区,只是为了给被回退掉的数据使用的每次回退就是在最前面(下表索引较小的位置)  写入数据

read

只要明确了unread以及内部缓冲区的存放形式即可很清楚的知道read的工作方式了

既然是从最后开始往前依次存放,初始时 pos == buf.length  那么但凡有数据,pos必然,小于buf.length也就是说,读取一个字节时,如果回退缓冲内有数据,直接返回一个字节否则,调用父类的read方法,而父类FilterInputStream 只是简单的 封装转发请求实际上就是直接使用内部的InputStream进行处理

多参数的read方法,将数据写入到指定的字节数组b中回退缓冲区中有效字节个数为avail = buf.length - pos;    如果缓冲区中有数据,那么将首先从回退缓冲区中读取数据如果读取的字节数少于 len 个字节,那么它将从底层输入流中读取字节

PushBackInputStream 不支持标记点相关的操作

总结

PushBackInputStream的实现逻辑比较清晰

我内部有一个缓冲区,你要是回退了我就往里面写入数据

每次的数据读取都是先看看缓冲区里面有没有数据,有的话就先读取回退缓冲区的

否则,就再去使用实际的流去进行读取

看得出来,如果你从来不曾回退过,那么好像什么都一样,还是使用原来的InputStream 进行读取

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏自动化测试实战

RF自定义系统关键字

41070
来自专栏微信公众号:Java团长

详解Java类的生命周期

最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目...

10920
来自专栏V站

如何提高PHP编程效率,提升程序编译质量(53条)

用单引号代替双引号来包含字符串,这样做会更快一些。因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串...

16950
来自专栏java一日一条

Java类的生命周期详解

最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题 讲明白的,主要是因为...

15630
来自专栏C语言C++游戏编程

七夕来了,请用C 语言和我交流

当我们提到输入时,这意味着要向程序填充一些数据。输入可以是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入,并根据需要填充到程序中。

12220
来自专栏老付的网络博客

程序如何运行的

在写代码的时候,我们直接在没有编译报错的时候,直接点击运行后,ide会直接把程序的结果输出到控制台上,代码如下:

20650
来自专栏决胜机器学习

设计模式专题(十五) ——组合模式

设计模式专题(十五)——组合模式 (原创内容,转载请注明来源,谢谢) 一、概述 组合模式(Composite)将对象组合成树形结构,以表示部分-整体的层次结构...

396110
来自专栏欧阳大哥的轮子

深入解构objc_msgSend函数的实现

熟悉OC语言的Runtime(运行时)机制以及对象方法调用机制的开发者都知道,所有OC方法调用在编译时都会转化为对C函数objc_msgSend的调用。

12020
来自专栏林德熙的博客

dotnet core 编程规范

本文实际只是翻译 .NET Core foundational libraries 官方文档的编码风格。

10220
来自专栏Python中文社区

有效的python属性管理:描述符的使用

專 欄 ❈Pytlab,Python中文社区专栏作者。主要从事科学计算与高性能计算领域的应用,主要语言为Python,C,C++。熟悉数值算法(最优化方法,蒙...

20290

扫码关注云+社区

领取腾讯云代金券