通常情况下使用输入流从磁盘、网络或者其它的物理介质读取数据都是按顺序读取的, 而在流的内部都会维护一个指针,读取数据的同时,指针会向后移动,直到读取完成为止。
而在一些实际常见中,如果读出来的数据不是想要的,但又放不回去的时候怎么办?
这时就可以使用IO提供的推回输入流。当使用普通的IO输入流如果读取到不想要的数据时,只能在程序里面处理掉,而使用IO里面的推回输入流读取数据则可以把数据给推回到输入流的缓冲区中。
推回输入流主要分为两类:分别是PushbackInputStream 和 PushbackReader
下面使用字符推回输入流 PushbackReader 举例说明推回输入流的应用,功能是:查找程序中 "//插入的字符串" 字符串,找到之后只是打印目标串之前的内容。
代码如下:
public static void main(String[] args) throws IOException {
// 创建字符输入流
Reader in = new FileReader("E:/MyJavacode/IOtest/z/HelloWorld.java");
// 创建推回输入流 指定推回缓冲区大小为64,
//如果不指定,默认缓冲区大小为1
PushbackReader reader = new PushbackReader(in, 64);
// 临时数组
char[] cs = new char[32];
// 读取的字符数
int count = 0;
// 记录上次读取的字符串
String strOld = "";
while ((count = reader.read(cs, 0, cs.length)) != -1) {
// 本次读取内容
String str = new String(cs, 0, count);
// 上次+本次读取内容 ‐‐ 避免 要查找的字符串被截断
String strContent = strOld + str;
// 查找目标字符串
// 目标出现位置
int targetIndex = strContent.indexOf("//插入的字符串");
if (targetIndex > -1) {
// 将本次内容和上次内容一起推回缓冲区
// ******推回缓冲区的内容大小不能超过缓冲区的大小
// 把strContent 推回流里
//int i = strContent.toCharArray().length;
reader.unread(strContent.toCharArray());
// 重新读取
if (targetIndex > 32) {
cs = new char[targetIndex];
}
// 再次读取指定长度的内容(就是目标字符串之前的内容)
reader.read(cs, 0, cs.length);
str = new String(cs);
System.out.print(str);
break;
} else {
// 为找到目标字符串
// 直接输出
System.out.print(strOld);
strOld = str;
}
}
reader.close();
}
运行效果如下: