filterinputstream 是 java 中用于装饰底层输入流的抽象基类,通过委托模式在不改变原流行为的前提下添加日志、解密、限速等逻辑;其子类需重写 read 等方法并直接调用 in.read() 避免递归。

FilterInputStream 是 Java I/O 中用于装饰(decorate)底层输入流的抽象基类,它本身不直接实现具体功能,而是提供一个标准包装结构,让你能方便地在读取数据过程中添加额外逻辑——比如日志、解密、限速、缓冲增强等。
理解 FilterInputStream 的设计意图
它继承自 InputStream,内部持有一个被包装的 InputStream(通常叫 in),所有读操作默认委托给这个底层流。你只需重写少数关键方法(如 read()、read(byte[])、skip()、available()),就能在不改变原始流行为的前提下插入自定义处理。
注意:Java 标准库已提供了多个现成子类,如 BufferedInputStream、PushbackInputStream、CheckedInputStream,它们都是基于 FilterInputStream 实现的典型例子。
自定义 FilterInputStream 的基本步骤
要扩展功能,你需要继承 FilterInputStream,并在构造器中传入目标流;然后按需重写读取方法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 重写
read():拦截单字节读取,可做预处理或后处理(如转换、计数、校验) - 重写
read(byte[] b, int off, int len):对批量读取加逻辑(如自动解密整块数据) - 若影响流状态(如跳过、标记/重置),记得同步更新或代理调用对应方法
- 避免在重写方法中直接调用
super.read(...)(因为 FilterInputStream 的 read 方法本身只是转发,容易造成无限递归)→ 应该调用in.read(...)
一个实用示例:统计已读字节数的 CountingInputStream
这个子类在每次读取时累加计数,便于监控或限流:
public class CountingInputStream extends FilterInputStream {
private long count = 0;
<pre class="brush:java;toolbar:false;">public CountingInputStream(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
int b = in.read(); // 直接调用底层流
if (b != -1) count++;
return b;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int n = in.read(b, off, len);
if (n > 0) count += n;
return n;
}
public long getCount() { return count; }}
使用方式和其他 InputStream 完全一致:
try (CountingInputStream cis = new CountingInputStream(new FileInputStream("data.bin"))) {
byte[] buf = new byte[1024];
while (cis.read(buf) != -1) { /* ... */ }
System.out.println("Total bytes read: " + cis.getCount());
}
注意事项与常见陷阱
-
不要重写 close() 除非必要:FilterInputStream 的
close()默认会关闭底层流;若需额外清理(如释放资源、刷新缓存),应先调用super.close()再执行后续操作 - mark/reset 支持需谨慎:如果底层流不支持 mark,则你的子类也不应声称支持;若要增强支持,得自己维护缓冲区
-
异常处理要透明:自定义逻辑中抛出的异常最好保留原始原因(用
throw new IOException("xxx", cause)),便于调试定位 - 性能敏感场景慎用多层包装:每层 FilterInputStream 都是一次方法调用开销,频繁小读可能放大影响
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










