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 : ...
随机推荐
- Async and Await (Stephen Cleary)
https://blog.stephencleary.com/2012/02/async-and-await.html Most people have already heard about the ...
- (八)爬虫之js调试(登陆知乎)
上次爬取网易云音乐,折腾js调试了好久,难受....今天继续练练手,研究下知乎登陆,让痛苦更猛烈些. 1.简单分析 很容易就发现登陆的url=“https://www.zhihu.com/api/v3 ...
- Flink简介
Flink简介 Flink的核心是一个流式的数据流执行引擎,其针对数据流的分布式计算提供了数据分布,数据通信以及容错机制等功能.基于流执行引擎,Flink提供了诸多更高抽象层的API以方便用户编写分布 ...
- Invoke-customs are only supported starting with Android O (--min-api 26) Message{kind=ERROR,……
https://www.jianshu.com/p/434928537a90 在我使用构建版本gradle 26但是在将buildtoolsversion更改为27之后,就像这个图像 错误:e ...
- linux内核中的wait_event_interruptible_timeout接口解析
1. 原型 #define wait_event_interruptible_timeout(wq_head, condition, timeout) \ ({ \ long __ret = time ...
- centos7.4出现yum command not found
购买的云服务器运行yum命令出现yum command not found. 通过将云主机自带的yum和python卸载掉,并且同时需要关注/usr/bin/yum文件的首行解释.我定义其为" ...
- 004-log-common-logging,Apache整合日志框架JCL门面框架、JCL+log4j
一.概述 Jakarta Commons Logging (JCL)提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具.它提供给中间件/日志工具开发者一个 ...
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_16.RabbitMQ研究-与springboot整合-生产者代码
springBoot给我们提供了 RarbbitTemplate发送消息 创建测试类,因为我们是基于SpringBoot的来写的测试类.所以要加上@SpringBootTest和@RunWith的注解 ...
- DSS分发压力实验
DSS分发压力实验 昨天为验证依托DSS搭建流媒体直播监控系统的可行性,及确定实时流画面出现严重花屏的原因,做了一个压力实验. 网络拓扑如图: 1.DVR上配置4路视频(CIF / 25fps / 1 ...
- js 匿名函数 js-函数定义方法
1.任何函数都是有返回值的,没有返回值的,在某些语言里称之为过程例如PL/SQL 2.js中的函数如果没有return 关键字指明给出的返回值,那么当调用完函数后,会返回“undefined" ...