功能简介
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 进行读取





[十三]JavaIO之PushBackInputStream的更多相关文章

  1. [二十三]JavaIO之PushbackReader

      功能简介   PushBackReader允许将字符推回到流的字符流 reader   PushBackReader 是一个装饰器模式最寻常的样子FilterReader 是抽象的装饰器模式 De ...

  2. [三]JavaIO之IO体系类整体设计思路 流的概念以及四大基础分类

    从本文开始,将正式进入JavaIO的简介 在继续javaIO系列的文章之前 可以过去看一下 本人博客上的设计模式中的 适配器模式和装饰器模式 这会对接下来的阅读大有帮助   本文是从逻辑上介绍整个的J ...

  3. [四] JavaIO之类层次体系结构横向比对

      IO家族类层次体系结构横向匹配   上一篇文章中主要介绍了JavaIO流家族的整体设计思路,简单回顾下 基本逻辑涉及数据源 流的方向,以及流的数据形式这三个部分的组合 按照流的数据形式和流的方向, ...

  4. [二十六]JavaIO之再回首恍然(如梦? 大悟?)

    流分类回顾 本文是JavaIO告一段落的总结帖 希望对JavaIO做一个基础性的总结(不涉及NIO) 从实现的角度进行简单的介绍 下面的这两个表格,之前出现过 数据源形式 InputStream Ou ...

  5. javaIO -- 流的体系设计思路、基础分类

    一.流 1. 流的含义 在程序设计中,流是对于数据流动传输的一种抽象描述任何有能力产出数据的数据源,或者有能力接受数据的接收端对象都是一个流. 2. 流的源和目的 数据可能从本地文件读取,或者写入,  ...

  6. CRL快速开发框架系列教程十三(嵌套查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  7. 我的MYSQL学习心得(十三) 权限管理

    我的MYSQL学习心得(十三) 权限管理 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  8. JavaIO学习笔记(五)

    JavaIO前期准备 什么是同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 什么是异步 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO ...

  9. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

随机推荐

  1. 如何用python下载一张图片

    如何用python下载一张图片 这里要用到的主要工具是requests这个工具,需要先安装这个库才能使用,该库衍生自urllib这个库,但是要比它更好用.多数人在做爬虫的时候选择它,是个不错的选择. ...

  2. PHP使用CURL抓取网页

    CURL是一个非常强大的开源库,支持很多协议,包括HTTP.FTP.TELNET等,我们使用它来发送HTTP请求.它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS ...

  3. 用python写一个非常简单的QQ轰炸机

    闲的没事,就想写一个QQ轰炸机,按照我最初的想法,这程序要根据我输入的QQ号进行轰炸,网上搜了一下,发现网上的案列略复杂,就想着自己写一个算了.. 思路:所谓轰炸机,就是给某个人发很多信息,一直刷屏, ...

  4. 调用获取学生信息的接口,保存到excel里面

    # 2.http: // doc.nnzhp.cn / index.php?s = / 6 & page_id = 14# 调用获取学生信息的接口,保存到excel里面 import requ ...

  5. Spring AOP Capabilities ang goals

    Spring AOP 是用纯JAVA 实现的. 不需借助JAVA代码在编译处理阶段来实现. Spring 是在运行期实现的.AOP的实现可以在编译,加载,运行三个阶段来实现:Spring AOP 也不 ...

  6. H5 _浏览器通知功能使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. WPF实现只打开一个窗口,并且重复打开时已经打开的窗口置顶

    内容来自:https://codereview.stackexchange.com/questions/20871/single-instance-wpf-application 第一步:添加Syst ...

  8. Base64简单原理

    Base64要求把每三个8bit的字节转换为四个6bit的字节(即3*8 = 4*6 = 24) 1.例如我们有一个中文字符“中国(gb2312)”,转为十进制为:中-->54992,国--&g ...

  9. [GIT] 更新.repo目录

    cd .repo/manifests/ git co -f git pull

  10. manacher算法,求回文串

    用来求字符串最长回文串或者回文串的总数量 #include<map> #include<queue> #include<stack> #include<cma ...