javaIO——PushbackReader
1. 注释解释:
A character-stream reader that allows characters to be pushed back into the stream.
一个允许字符被推回到流中的字符流读取器。(可能“推回”这个词不太准确)
根据我们以往对输入流的的认知,它应该是单向的,被从头到尾依次读取。即使有些流 提供 mark 功能,那也是造成对某一部分的重复读取,不会产生流数据源本身不包含的字符。但是 PushbackReader 不一样,它允许调用者将一些数据源本身不包含的字符插入到流的任意位置,下面我们来看看实现原理。
2. 定义
首先我们来看看它的定义和构造方法:

可以看出,PushbackReader 继承自 FilterReader,查看过 FilterReader 源码,只是对 Reader 的一个通用包装类,没有什么特殊功能的添加(可能只是为了以后扩展)。而想要构造一个有意义 PushbackReader,必须向构造方法传递一个 Reader 实例(否则 ensureOpen 方法校验不通过),构造方法会初始化一个回退缓冲区和缓冲区位置指针,这两个便是 PushbackReader 的关键字段了。
3. 核心方法
3.1. read 方法


可以看出,read 方法都会优先从缓冲区读取数据。其中,缓冲区 pos 指针在最后表示缓冲区没有数据了。那么缓冲区的数据哪里来的呢?下面看看 unread 方法。
3.2. unread 方法
unread 方法就是该类最核心的方法了,它允许调用者通过该方法将数据填充到缓冲区,然后在 read 时被优先读取。


可以看出,unread 方法将数据从缓冲区的后面向前面填充到缓冲区,然后 read 从前向后读取,类似一个栈结构。但是注意,单次回推的字符序列并不会逆序,而是作为一个整体。所以 unread 和 read 并不是一个简单的逆序过程。
4. 总结
4.1. PushbackReader 提供 unread 方法,允许使用者将自定义的数据插入到输入流中;
4.2. 插入的数据被保存在缓冲区中,一旦缓冲区中有数据插入,那么下次读取将会优先读取缓冲区;
4.3. 后插入的数据,先读取(但单次插入的并不会被逆序);
5. 举例
假如输入流源数据为字符串 “123456789”,那么当读取 “123” 之后分别执行 unread 推回这几个串:“abc”、“de”、“fghi”,那么最终读取完成后的结果就是 “123fghideabc456789” 。
6. 验证
下面我们来编写代码测试一下,为了简单起见我把被包装的 Reader 类使用 StringReader :
public class PushbackReaderTest {
public static void main(String[] args) throws IOException {
StringReader stringReader = new StringReader("123456789");
PushbackReader pushbackReader = new PushbackReader(stringReader, 100);
StringBuilder stringBuilder = new StringBuilder();
char[] buff = new char[100];
//第一步,首先读取 “123”
int n = pushbackReader.read(buff, 0, 3);
stringBuilder.append(buff);
System.out.println("第一步,读取了 " + n + " 个字符:");
System.out.println(buff);
//第二步,unread:abc, de, fghi
pushbackReader.unread(new char[]{'a', 'b', 'c'});
pushbackReader.unread(new char[]{'d', 'e'});
pushbackReader.unread(new char[]{'f', 'g', 'h', 'i'});
int c = 0;
while (c != -1){
c = pushbackReader.read();
stringBuilder.append((char) c);
}
System.out.println("最终读取的数据:" + stringBuilder.toString());
}
}
测试结果:

javaIO——PushbackReader的更多相关文章
- [二十三]JavaIO之PushbackReader
功能简介 PushBackReader允许将字符推回到流的字符流 reader PushBackReader 是一个装饰器模式最寻常的样子FilterReader 是抽象的装饰器模式 De ...
- [三]JavaIO之IO体系类整体设计思路 流的概念以及四大基础分类
从本文开始,将正式进入JavaIO的简介 在继续javaIO系列的文章之前 可以过去看一下 本人博客上的设计模式中的 适配器模式和装饰器模式 这会对接下来的阅读大有帮助 本文是从逻辑上介绍整个的J ...
- [四] JavaIO之类层次体系结构横向比对
IO家族类层次体系结构横向匹配 上一篇文章中主要介绍了JavaIO流家族的整体设计思路,简单回顾下 基本逻辑涉及数据源 流的方向,以及流的数据形式这三个部分的组合 按照流的数据形式和流的方向, ...
- [二十六]JavaIO之再回首恍然(如梦? 大悟?)
流分类回顾 本文是JavaIO告一段落的总结帖 希望对JavaIO做一个基础性的总结(不涉及NIO) 从实现的角度进行简单的介绍 下面的这两个表格,之前出现过 数据源形式 InputStream Ou ...
- javaIO -- 流的体系设计思路、基础分类
一.流 1. 流的含义 在程序设计中,流是对于数据流动传输的一种抽象描述任何有能力产出数据的数据源,或者有能力接受数据的接收端对象都是一个流. 2. 流的源和目的 数据可能从本地文件读取,或者写入, ...
- JavaIO学习笔记(五)
JavaIO前期准备 什么是同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 什么是异步 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO ...
- javaIO系统----再看装饰者模式
javaIO系统拥有各种各样的类,尤其是每次要进行读写操作时,总会一层套一层的new,以前不明白为什么要这样做,不过学习了适配器模式后,对于这种做法立刻了解了:动态扩展IO的功能,使之符合使用者的习惯 ...
- Java学习日记之 Java-IO流
Java中的IO流在处理上分为字节流和字符流.字节流和字符流的区别 : 1.字节流读取的时候,读到一个字节就返回一个字节: 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8 ...
- javaIO框架小析
IO即数据读写.数据是应用的中心要素,而数据读写的能力和可扩展性是编程平台的基础支撑. 概念框架 方式: 字节流 Byte 和 字符流 Char 方向: 输入 Input 和 输出 Output : ...
随机推荐
- Jenkins 自动化部署上线
转载于互联网 jenkins自动化部署项目,通过jenkins 部署来节省运维时间,不需要手动cp上线及版本发布 Jenkins 自动化部署上线 Jenkins Jenkins 自动化部署上线一.Je ...
- OpenStack Cinder发展动态系列--Austin峰会
在Mitaka版本,Cinder团队在多个特性和领域取得了重大进展. 本文将做一个简要的介绍:关于在Mitaka版本已经完成的功能和特性,以及讨论在Newton版本将会开发的功能和特性. 1 Cind ...
- Bash Shellshock(CVE-2014-6271)破壳漏洞测试
0x01 漏洞原理 Bash使用的环境变量是通过函数名称来调用的,导致漏洞出问题是以"(){"开头定义的环境变量在命令ENV中解析成函数后,Bash执行并未退出,而是继续解析并执行 ...
- iOS开发需要安装的工作软件
1 源代码管理工具 SVN:SVN可以使用的客户端软件有Cornerstone,SmartSVN,svnX,乌龟SVN,莲花版svn等 或者git(sourcetree) 2 有道词典 3 Foxma ...
- leetcode 将一个二维矩阵进行90度旋转
import numpy as np import math if __name__ == '__main__': def rotate(matrix): n = len(matrix[0]) for ...
- Kuhn-Munkras算法解决二分图最优权值匹配
在看这篇博文之前建议看一下上一篇匈牙利法解决二分图最大匹配问题: https://www.cnblogs.com/fangxiaoqi/p/10808729.html 这篇博文参考自:https:// ...
- python使用socket向客户端发送数据的方法
在使用locust测试长连接的时候,所有的请求全部faillure了,所以想到手动写一个连接脚本测试一下是否能连通 因为centos7自带python2.7所以用python写一个比较方便. #!/u ...
- MySQL之LEFT JOIN中使用ON和WHRERE对表数据
背景 left join在我们使用mysql查询的过程中可谓非常常见,比如博客里一篇文章有多少条评论.商城里一个货物有多少评论.一条评论有多少个赞等等.但是由于对join.on.where等关键字的不 ...
- Insomni’hack CTF-l33t-hoster复现分析
题目地址: https://github.com/eboda/insomnihack/tree/master/l33t_hoster 源码如下: <?php if (isset($_GET[&q ...
- 获取淘宝客推广位id(adzone_id)
在 获取淘宝联盟选品库的宝贝信息 这个接口中需要用到 推广位id,那边这个ID在哪找呢?1.进入阿里妈妈后台>推广管理>推广位管理,如下图: 2.在推广位管理 列表页 找到 PID,最后一 ...