io 9.0 推回输入流

推回输入流

在输入/输出流体系中,有两个特殊的流与众不同,就是PushbackInputStream和PushbackReader,它们都提供了如下三个方法。

  • void unread(byte[]/char[] buf):将一个字节/字符数组内容推回到推回缓冲区里,从而允许重复读取刚刚读取的内容。

  • void unread(byte[]/char[] b, int off, int len):将一个字节/字符数组里从off开始,长度为len字节/字符的内容推回到推回缓冲区里,从而允许重复读取刚刚读取的内容。

  • void unread(int b):将一个字节/字符推回到推回缓冲区里,从而允许重复读取刚刚读取的内容。

发现了这三个方法与InputStream和Reader中的三个read()方法一一对应,没错,这三个方法就是PushbackInputStream和PushbackReader的奥秘所在。

这两个推回输入流都带有一个推回缓冲区,当程序调用这两个推回输入流的unread()方法时,系统将会把指定数组的内容推回到该缓冲区里,而推回输入流每次调用read()方法时总是先从推回缓冲区读取,只有完全读取了推回缓冲区的内容后,但还没有装满read()所需的数组时才会从原输入流中读取。
在这里插入图片描述

根据上面的介绍可以知道,当程序创建一个PushbackInputStream和PushbackReader时需要指定推回缓冲区的大小,默认的推回缓冲区的长度为1。如果程序中推回到推回缓冲区的内容超出了推回缓冲区的大小,将会引发Pushback buffer overflow的IOException异常。

注意:
虽然图中的推回缓冲区的长度看似比read()方法的数组参数的长度小,但实际上,推回缓冲区的长度与read()方法的数组参数的长度没有任何关系,完全可以更大。

下面程序试图找出程序中的"new PushbackReader"字符串,当找到该字符串后,程序只是打印出目标字符串之前的内容。

public class PushbackTest {

    public static void main(String[] args) {
        try (
                PushbackReader pushbackReader = new PushbackReader(new FileReader("src\\com\\rrz\\PushbackTest.java"), 64)
        ) {
            int hasRead;
            char[] chars = new char[32];
            String lastContext = "";

            while ((hasRead = pushbackReader.read(chars)) > 0) {
                String context = new String(chars);
                // 如果上次和这次拼接的字符串包含指定字符串,则推回
                int index;
                if ((index = (lastContext + context).indexOf("new PushbackReader")) > 0) {
                    // 推回
                    pushbackReader.unread((lastContext+context).toCharArray(), 0, index);

                    if (index > chars.length) {
                        chars = new char[index];
                    }
                    pushbackReader.read(chars, 0, index);
                    System.out.println(new String(chars, 0, index));
                    System.exit(0);
                } else {
                    System.out.println(lastContext);
                    lastContext = context;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

上面粗体字代码实现了将指定内容推回到缓冲区,于是当程序再次调用 read()方法时,实际上只是读取了 推回缓冲区的部分内容,从而实现了只打印目标字符串前面内容的功能。

上一节:转换流
下一节:重定向标准输入标准输出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值