Java_io体系之FilterInputStream/FilterOutputStream简介、走进源码及示例——07
2013-11-25 23:12
816 查看
Java_io体系之FilterInputStream/FilterOutputStream简介、走进源码及示例——07
一:FilterInputStream
1、 类功能简介:
过滤器字节输入流、这里不得不提到一种设计模式:Decorator模式、Decorator模式又名包装器(Wrapper),它的主要用途在于给一个对象动态的添加一些额外的职责。与生成子类相比,它更具有灵活性。有时候,我们需要为一个对象而不是整个类添加一些新的功能,比如,给一个文本区添加一个滚动条的功能。我们可以使用继承机制来实现这一功能,但是这种方法不够灵活,我们无法控制文本区加滚动条的方式和时机。而且当文本区需要添加更多的功能时,比如边框等,需要创建新的类,而当需要组合使用这些功能时无疑将会引起类的爆炸。
我们可以使用一种更为灵活的方法,就是把文本区嵌入到滚动条中。而这个滚动条的类就相当于对文本区的一个装饰。这个装饰(滚动条)必须与被装饰的组件(文本区)继承自同一个接口,这样,用户就不必关心装饰的实现,因为这对他们来说是透明的。装饰会将用户的请求转发给相应的组件(即调用相关的方法),并可能在转发的前后做一些额外的动作(如添加滚动条)。通过这种方法,我们可以根据组合对文本区嵌套不同的装饰,从而添加任意多的功能。这种动态的对对象添加功能的方法不会引起类的爆炸,也具有了更多的灵活性。
以上的方法就是Decorator模式,它通过给对象添加装饰来动态的添加新的功能。
Exp:
当构造FilterInputStream传递进来的是ByteArrayInputStream、因为FilterInputStream与ByteArrayInputStream实现的是同一接口InputStream、那么FileterInputStream对ByteArrayInputStream的装饰对于使用者来说是透明的、他可以在ByteArrayInputStream从父类继承的方法执行之前或者之后进行一些额外操作、实现装饰作用、这里不得不提一句、FilterInputStream仅仅对对InputStream中所有方法进行了重写、并且只调用传入的InputStream子类(一般是低级字节输入流)的那些实现InputStream中的方法、换句话说就是没有对传入的低级字节输入流进行任何的装饰、他的作用是为所有作为装饰类的字节输入流提供一个标准、一个类似于接口的作用。具体的装饰由其子类来完成。
更多内容可以看看前面的:java——IO设计模式:http://blog.csdn.net/crave_shy/article/details/14613423
2、 FilterInputStreamAPI简介:
A:关键字段
//接收构造函数传递进来的 InputStream具体实现类。 protected volatile InputStream in;
B:构造方法
// 根据传入的InputStream具体实现类创建FilterInputStream protected FilterInputStream(InputStream in) { this.in = in; }
C:一般方法
int avaliable();查看当前流中可供读取的字节数。 void close();关闭当前流、释放所有与当前流有关的资源。 synchronized void mark(int readlimit);标记当前流的读取的位子。 boolean markSupport();查看当前流是否支持mark。 int read();读取当前流中的下一个字节、并以整数形式返回、若读取到文件结尾则返回-1。 int read(byte[] b);将当前流中的字节读取到字节数组b中、返回实际读取的字节数 int read(byte[] b, int off, int len);将当前流中的len个字节读取到从下标off开始存放的字节数组b中。 synchronized reset();重置当前流的读取位置到最后一次调用mark方法标记的位置。 long skip(long n);跳过(抛弃)当前流中n个字节。返回实际抛弃的字节数。
3、 源码分析:
package com.chy.io.original.code; import java.io.IOException; /** * FileterInputStream 过滤器字节输入流 、本身什么事都没有做、只是简单的重写InputStream的所有方法。 */ public class FilterInputStream extends InputStream { /** * 接收构造函数传递进来的 InputStream具体实现类。 * 至于 volatile 关键字的意义 参见:http://blog.csdn.net/crave_shy/article/details/14610155 */ protected volatile InputStream in; /** * 根据传入的InputStream具体实现类创建FilterInputStream、并将此实现类赋给全局变量 in、方便重写此实现类从InputStream继承的或重写的所有方法。 */ protected FilterInputStream(InputStream in) { this.in = in; } /** * 具体InputStream实现类的read()方法、若子类自己实现的、则是子类的、若子类没有实现则用的是InputStream本身的方法。 * 下面的方法一样。若有不明白的可见前面的InputStream源码分析。 */ public int read() throws IOException { return in.read(); } 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 long skip(long n) throws IOException { return in.skip(n); } public int available() throws IOException { return in.available(); } public void close() throws IOException { in.close(); } public synchronized void mark(int readlimit) { in.mark(readlimit); } public synchronized void reset() throws IOException { in.reset(); } public boolean markSupported() { return in.markSupported(); } }
4、 实例演示:
因为其只是一个标准、其方法都是调用传入的InputStream实现类的方法、意义大过于作用、所以这里暂不提供实例、会在有实际装饰效果的类中提供实例、比如后面的DataInputStream、BufferedInputStream、等装饰类的文章中贴出。二:FilterOutputStream
1、 类功能简介:
过滤字节输出流、与此类是过滤输出流的所有类的超类。这些流位于已存在的输出流(基础输出流)之上,它们将已存在的输出流作为其基本数据接收器,但可能直接传输数据或提供一些额外的功能。FilterOutputStream类本身只是简单地重写那些将所有请求传递给所包含输出流的
OutputStream的所有方法。
FilterOutputStream的子类可进一步地重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。这是API中关于此流的原话、与对上面FilterInputStream的理解做个对比、多方面的去理解、对比更可以加深印象。
2、 FilterInputStreamAPI简介:
A:关键字段
//传入的OutputStream实现类的引用 protected OutputStream out;
B:构造方法
//通过传入的OutputStream实现类构造FilterOutputStream public FilterOutputStream(OutputStream out) { this.out = out; }
C:一般方法
void write(byte b);将一个字节写入到当前输出流管道中。 void write(byte[] b);将字节数组b中所有字节写入到当前输出流管道中。 void write(byte[] b, int off, int len);将字节数组b从下标off开始、len个字节写入当前输出流管道中 void flush();flush当前流、将当前流中的所有数据冲刷到目的地中。 void close();关闭当前流、释放与当前流有关的所有资源。
3、 源码分析:
package com.chy.io.original.code; import java.io.IOException; /** * 与FilterOutputStream基本相同、 */ public class FilterOutputStream extends OutputStream { /** * 与FileterInputStream 的区别就是不再是volatile */ protected OutputStream out; //通过传入的OutputStream实现类构造FilterOutputStream public FilterOutputStream(OutputStream out) { this.out = out; } public void write(int b) throws IOException { out.write(b); } public void write(byte b[]) throws IOException { write(b, 0, b.length); } public void write(byte b[], int off, int len) throws IOException { if ((off | len | (b.length - (len + off)) | (off + len)) < 0) throw new IndexOutOfBoundsException(); for (int i = 0 ; i < len ; i++) { write(b[off + i]); } } public void flush() throws IOException { out.flush(); } /** * 关闭此流之前会flush一下。 */ public void close() throws IOException { try { flush(); } catch (IOException ignored) { } out.close(); } }