Java IO 教程

Java IO:FilterReader 类

在 Java 里,FilterReader 类处于 java.io 包中,它是一个抽象类,继承自 Reader。该类的主要作用是为其他 Reader 提供一个过滤机制。FilterReader 类本身不执行任何过滤操作,它仅仅是作为一个基础,让开发者可以继承它并实现自定义的过滤逻辑。

FilterReader 包含一个受保护的 Reader 对象,该对象用于读取数据,而 FilterReader 则在这些数据被读取时进行过滤处理。通过继承 FilterReader,你能够创建自定义的过滤器,在读取字符流时对数据进行修改、转换或者选择性地读取。

下面是 FilterReader 的部分源码:

package java.io;

public abstract class FilterReader extends Reader {
    // 底层字符输入流
    protected Reader in;

    protected FilterReader(Reader in) {
        super(in);
        this.in = in;
    }

    public int read() throws IOException {
        return in.read();
    }

    public int read(char cbuf[], int off, int len) throws IOException {
        return in.read(cbuf, off, len);
    }

    public long skip(long n) throws IOException {
        return in.skip(n);
    }

    public boolean ready() throws IOException {
        return in.ready();
    }
    
    public boolean markSupported() {
        return in.markSupported();
    }

    public void mark(int readAheadLimit) throws IOException {
        in.mark(readAheadLimit);
    }

    public void reset() throws IOException {
        in.reset();
    }

    public void close() throws IOException {
        in.close();
    }

}

FilterReader 是一个基类,用于实现自己的过滤阅读器。基本上,它只是覆盖了 Reader 中的所有方法。

和 FilterInputStream 一样,我看不出该类有什么合理的用途。除了在构造函数中使用一个 Reader 之外,我看不出该类实际上增加或改变了 Reader 中的任何行为。如果你选择扩展该类,还不如直接扩展 Reader 类,避免在层次结构中增加额外的类。

FilterReader 常见子类

以下是 FilterReader 的一些常见子类及其作用:

PushbackReader

PushbackReader 允许你将已经读取的字符推回到输入流中,以便后续再次读取。这在进行词法分析、语法解析等场景中非常有用,因为在解析过程中可能会提前读取一些字符来判断后续的处理逻辑,但发现这些字符不适合当前的处理步骤,此时就可以将它们推回输入流,等待合适的时机再处理。

LineNumberReader

LineNumberReader 用于跟踪当前读取的行号。它在读取字符流时会自动记录行号,你可以通过调用 getLineNumber() 方法获取当前的行号。这在处理文本文件时非常有用,特别是在需要定位错误信息或进行调试时,能够方便地知道错误发生在哪一行。

BufferedReader

虽然 BufferedReader 主要用于提供缓冲功能以提高读取效率,但它也间接继承自 FilterReader。它通过缓冲机制,一次从底层输入流读取一大块数据到缓冲区,然后从缓冲区中逐个字符地返回给调用者,减少了与底层输入流的交互次数,从而提高了读取性能。

StreamTokenizer

StreamTokenizer 是一个特殊的 FilterReader 子类,用于将输入流解析为一系列的标记(token)。它可以识别不同类型的标记,如单词、数字、标点符号等,并将输入流按照标记进行分割。这在进行文本处理、词法分析等场景中非常有用。

自定义 FilterReader

下面为你展示一个自定义 FilterReader 的示例,该示例会过滤掉输入文本里的所有小写字母:

package com.hxstrive.java_io;

import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

// 自定义 FilterReader 类,继承自 FilterReader
class CustomFilterReader extends FilterReader {

    // 构造函数,接收一个 Reader 对象
    protected CustomFilterReader(Reader in) {
        super(in);
    }

    // 重写 read() 方法,过滤小写字母
    @Override
    public int read() throws IOException {
        int c;
        // 循环读取字符,直到遇到非小写字母或文件结束
        while ((c = super.read()) != -1) {
            if (!Character.isLowerCase(c)) {
                return c;
            }
        }
        return -1;
    }

    // 重写 read(char[] cbuf, int off, int len) 方法
    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int numChars = super.read(cbuf, off, len);
        if (numChars == -1) {
            return -1;
        }
        int pos = off;
        for (int i = off; i < off + numChars; i++) {
            if (!Character.isLowerCase(cbuf[i])) {
                cbuf[pos++] = cbuf[i];
            }
        }
        return pos - off;
    }

    public static void main(String[] args) {
        String input = "Hello, World! 123";
        // 创建一个 StringReader 对象,用于读取输入字符串
        try (StringReader sr = new StringReader(input);
             // 创建自定义的 FilterReader 对象
             CustomFilterReader cfr = new CustomFilterReader(sr)) {
            int c;
            // 循环读取过滤后的字符并输出
            while ((c = cfr.read()) != -1) {
                System.out.print((char) c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出:
        //H, W! 123
    }

}

注意,CustomFilterReader 类继承自 FilterReader,重写了 read() 和 read(char[] cbuf, int off, int len) 方法。在 read() 方法里,它会持续读取字符,直至遇到非小写字母或者文件结束。在 read(char[] cbuf, int off, int len) 方法中,它会过滤掉字符数组里的小写字母。

在 main() 方法中,创建了一个 StringReader 对象来读取输入字符串,接着创建 CustomFilterReader 对象对输入进行过滤,最后把过滤后的字符输出。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号