filterinputstream 是基于装饰器模式的抽象类,通过包装并委托底层 inputstream 实现功能增强;子类可选择性重写方法,常见子类包括 bufferedinputstream、datainputstream 等。

FilterInputStream 是 Java IO 中用于装饰基础输入流的抽象类,它本身不直接处理数据,而是把读取操作委托给被包装的底层流(如 FileInputStream 或 ByteArrayInputStream),同时在调用前后插入自定义逻辑,实现功能增强。
核心机制:包装+委托
FilterInputStream 的设计基于装饰器模式。它持有一个 InputStream 引用(通常在构造时传入),所有读取方法(如 read()、read(byte[])、skip()、available())默认只是调用被包装流的对应方法。子类只需重写需要增强的方法即可,无需重复实现整个流协议。
- 构造时必须传入一个非 null 的
InputStream,否则抛NullPointerException - 子类可选择性重写部分方法,比如只增强
read()而保留skip()的原始行为 - 所有未重写的方法自动继承父类的委托逻辑,保证基础功能不丢失
常见子类及扩展方向
Java 标准库中多个实用类继承自 FilterInputStream,体现了不同扩展目标:
-
BufferedInputStream:添加缓冲区,减少底层系统调用次数,提升连续读取性能 -
DataInputStream:提供readInt()、readUTF()等方法,支持基本类型和字符串的二进制解析 -
PushbackInputStream:允许将已读字节“推回”流中,便于实现简单词法分析(如 peek 操作) -
CheckedInputStream:在读取同时计算校验和(如 CRC32),用于数据完整性校验
自定义 FilterInputStream 示例
比如实现一个统计已读字节数的计数流:
<font size="2">public class CountingInputStream extends FilterInputStream {
private long count = 0;
public CountingInputStream(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
int b = super.read();
if (b != -1) count++;
return b;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int n = super.read(b, off, len);
if (n > 0) count += n;
return n;
}
public long getCount() { return count; }
}</font>
使用时可链式包装:new CountingInputStream(new BufferedInputStream(new FileInputStream("data.txt"))),既享受缓冲性能,又获得精确字节统计。
注意事项与限制
- FilterInputStream 只增强“读取”行为,不提供写或重置能力;若需 mark/reset,需确保底层流支持,且子类未破坏该语义
- 关闭流时应调用
close(),它会自动关闭被包装的流(除非子类重写且未调用super.close()) - 不建议直接实例化 FilterInputStream,它仅作为基类存在,必须由子类实现具体逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











