在 java 字节流与字符流中,filterreader 是用于包装现有 reader 以实现特定功能(如缓冲、过滤或转换)的抽象基类。要使用它,你需要继承 filterreader 并实现其核心的 read() 方法,或者直接使用其子类(如 bufferedreader)。通过构造器传入一个现有的 reader 实例,即可在读取数据时插入自定义逻辑。

如何继承 FilterReader 实现一个简单的过滤功能
直接继承 FilterReader 并重写 read() 方法,可以在读取字符时进行过滤。例如,创建一个只允许读取非空格字符的过滤器。通过调用 super(reader) 将底层 Reader 传递给父类,然后在 read() 中循环读取直到找到符合条件的字符或遇到 EOF。

import java.io.*;
public class NonSpaceFilterReader extends FilterReader {
protected NonSpaceFilterReader(Reader in) {
super(in);
}
@Override
public int read() throws IOException {
int c = super.read();
while (c != -1 && Character.isWhitespace(c)) {
c = super.read();
}
return c;
}
public static void main(String[] args) throws IOException {
String input = "Hello World";
try (NonSpaceFilterReader reader = new NonSpaceFilterReader(new StringReader(input))) {
int c;
StringBuilder sb = new StringBuilder();
while ((c = reader.read()) != -1) {
sb.append((char) c);
}
System.out.println(sb.toString()); // 输出: HelloWorld
}
}
}
为什么通常推荐使用 BufferedReader 而不是直接继承 FilterReader
虽然可以直接继承 FilterReader,但在实际开发中,更常见的是使用 BufferedReader 来包装 Reader 以获得缓冲功能,提高 I/O 性能。BufferedReader 本身也是 FilterReader 的子类,它内部维护了一个缓冲区,减少了系统调用的次数。直接继承 FilterReader 适合需要精细控制每个字符处理逻辑的场景,而 BufferedReader 适合大多数需要提升读取效率的场景。
立即学习“Java免费学习笔记(深入)”;

import java.io.*;
public class BufferedExample {
public static void main(String[] args) throws IOException {
String input = "Hello\nWorld";
try (BufferedReader reader = new BufferedReader(new StringReader(input))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
}
当底层 Reader 抛出 IOException 时,FilterReader 如何处理
如果底层 Reader 在读取过程中抛出 IOException,FilterReader 会直接将异常向上抛出,不会吞没或转换异常类型。这意味着调用者必须处理或声明该异常。在上面的 NonSpaceFilterReader 示例中,如果底层 StringReader 抛出异常,read() 方法中的 super.read() 会触发异常传播。因此,在使用自定义 FilterReader 时,确保正确处理 IOException 是关键。


















