功能简介
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. 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习4

    #include <iostream> using namespace std; const int strsize=30; const int BOPSIZE=5; void showm ...

  2. 浏览器url地址殊字符转义编码

    网址URL中特殊字符转义编码字符    -    URL编码值 空格    -    %20"          -    %22#         -    %23%        -   ...

  3. 理解pytorch中的softmax中的dim参数

    import torch import torch.nn.functional as F x1= torch.Tensor( [ [1,2,3,4],[1,3,4,5],[3,4,5,6]]) y11 ...

  4. spring-cloud-gateway负载普通web项目

    spring-cloud-gateway负载普通web项目 对于普通的web项目,也是可以通过spring-cloud-gateway进行负载的,只是无法通过服务发现. 背景 不知道各位道友有没有使用 ...

  5. golang二进制bit位的常用操作

    golang作为一热门的兼顾性能 效率的热门语言,相信很多人都知道,在编程语言排行榜上一直都是很亮眼,作为一门强类型语言,二进制位的操作肯定是避免不了的,数据的最小的单位也就是位,尤其是网络中封包.拆 ...

  6. 在浏览器输入URL时发生了什么

    浏览器器检查cache,如果请求对象已经缓存并且是最新的,执行第9步. 浏览器询问操作系统,请求服务器的IP地址 操作系统进行DNS查找,然后告诉浏览器服务器的IP 浏览器和服务器简历一个TCP连接( ...

  7. Ubuntu下安装Pycharm出现unsupported major.minor version 52.0

    (一)原因 Ubuntu下pycharm安装:https://jingyan.baidu.com/article/60ccbceb4e3b0e64cab19733.html pycharm激活:htt ...

  8. mysql爱之深探测

    第一:函数 一:内置函数 MYSQL中提供了很多内置的函数,以下: CHAR_LENGTH(str) 返回值为字符串str 的长度,长度的单位为字符.一个多字节字符算作一个单字符. 对于一个包含五个二 ...

  9. 微信小程序----没有 DOM 对象,一切基于组件化 ---- mpvue

    封装好用的 类库 和 组件,复用且灵活度高 抽取相同的部分放在函数内部(组件内部) 抽取不同的部分放在形参(组件 props 传参,或者插槽) new Promise 运行时 初始化实例对象的状态为 ...

  10. 通过cmd命令,杀掉占用端口号的进程

    错误问题:[Error running public: Unable to open debugger port (127.0.0.1:53110): java.net.BindException & ...