FilterInputStream:仅仅覆盖了InputStream的所有方法。其子类对这些方法提供了更具体的实现,并提供了额外的功能。
相当于Decorator(抽象装饰者角色)。
FilterInputStream源码:
//保存对InputStream的引用;多线程即时可见
protected volatile InputStream in;
//构造函数
protected FilterInputStream(InputStream in) {
this.in = in;
}
//数据流的下一个字节;如果流已读完,返回-1
public int read() throws IOException {
return in.read();
}
//读取的字节放入b[]数组中,返回读取的字节总数;流已读完,返回-1
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
//关闭输入流,释放资源;不可在读
public void close() throws IOException {
in.close();
}
//返回可以读入的字节数量
public int available() throws IOException {
return in.available();
}
//标记流的当前位置,调用reset时,从最后一次mark的位置重新read.
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
//重新定位流位置于最后一次mark位置。
public synchronized void reset() throws IOException {
in.reset();
}
//判断是否支持mark/reset方法
public boolean markSupported() {
return in.markSupported();
}
从以上源码可以看出,FilterInputStream将所有的操作都委托给了in这个成员变量。子类在实例化时,传入in的引用,一般为ConcreteComponent实例的引用
BufferedInputStream使用举例:
// 创建ConcreteComponent(具体组件角色)
InputStream is = new FileInputStream("d://test.txt");
//将ConcreteComponent的引用传入ConcreteDecorator
FilterInputStream fis = new BufferedInputStream(is);
//执行fis的方法
System.out.println((char) fis.read());
fis.mark(0);
System.out.println((char) fis.read());
fis.reset();
BufferedInputStream的实例是具体装饰者角色,FileInputStream的实例是具体组件角色。BufferedInputStream在FileInputStream的基础上增加了额外的功能,如具体实现了mark,reset方法。