</p> 同样,它也是从OutputStream继承。但是,它的构造函数很特别,需要传递一个OutputStream的引用给它,并且它将保存对此对象的引用。而如果没有具体的OutputStream对象存在,我们将无法创建FilterOutputStream。由于out既可以是指向 FilterOutputStream类型的引用,也可以是指向ByteArrayOutputStream等具体输出流类的引用,因此使用多层嵌套的方式,我们可以为ByteArrayOutputStream添加多种装饰。这个FilterOutputStream类相当于Decorator模式中的 Decorator类,它的write(int b)方法只是简单的调用了传入的流的write(int b)方法,而没有做更多的处理,因此它本质上没有对流进行装饰,所以继承它的子类必须覆盖此方法,以达到装饰的目的。
5 h* e2 Z. A0 X; y& _4 Z BufferedOutputStream 和 DataOutputStream是FilterOutputStream的两个子类,它们相当于Decorator模式中的 ConcreteDecorator,并对传入的输出流做了不同的装饰。以BufferedOutputStream类为例:, U2 t# v+ L" {: ]" @% R
以下是代码片段:
7 V9 u# e4 o2 e8 q8 g9 Q" B public class BufferedOutputStream extends FilterOutputStream {7 @/ D0 P. N" q1 P
...) r* p/ |/ P* [/ j
private void flushBuffer() throws IOException {" D% H! }' I7 u, N6 d b, i
if (count 〉 0) {
' q, a' ^1 v/ f1 j6 O3 A out.write(buf, 0, count);
. t. O$ J8 ?, Q+ n4 ^1 K count = 0;
2 v9 \& J5 Z, E& Y2 Z$ [7 I# S+ W }/ \0 L/ R1 C: B) R/ R. i+ B
}1 @' P" m1 y+ i s, O
public synchronized void write(int b) throws IOException {
# [3 N& [2 x" l Y& W! N' C" _: t, C if (count 〉= buf.length) {
; }7 _5 j( V: L8 I5 I$ G! ^9 z+ _ v7 z flushBuffer();7 v3 g, w ]$ k
}+ f; r% |6 ^1 \0 Z
buf[count++] = (byte)b;
' S, M: P8 u0 o# p- V/ f }* O3 i6 h" o3 ~, x4 \) G! ?
...
. q8 `$ J- ~2 T1 c }
% L% e5 V/ e' P( _% W 这个类提供了一个缓存机制,等到缓存的容量达到一定的字节数时才写入输出流。首先它继承了FilterOutputStream,并且覆盖了父类的write(int b)方法,在调用输出流写出数据前都会检查缓存是否已满,如果未满,则不写。这样就实现了对输出流对象动态的添加新功能的目的。
2 g8 W% q" F0 K7 p 下面,将使用Decorator模式,为IO写一个新的输出流。
8 G1 \ L4 L1 w 自己写一个新的输出流
y( z" s# y9 W 了解了OutputStream及其子类的结构原理后,我们可以写一个新的输出流,来添加新的功能。这部分中将给出一个新的输出流的例子,它将过滤待输出语句中的空格符号。比如需要输出"java io OutputStream",则过滤后的输出为"javaioOutputStream"。以下为SkipSpaceOutputStream类的代码:
4 \2 y3 w+ b; y; D2 e8 ] 以下是代码片段:
& H! Z: ~1 g# l$ L6 } import java.io.FilterOutputStream;4 }' C& K& h( h! ?9 @: m# X& R+ v
import java.io.IOException;
) D( t' ?( Z4 {$ ~* Z8 W& G import java.io.OutputStream;
- [! [* T+ B. ]( I# R$ P5 J /**
% Z d& V' D- Z6 [1 o6 M2 y * A new output stream, which will check the space character/ m, u* v' H- Z3 V. ^7 N' @
* and won’t write it to the output stream.( O) F" n! I3 g, o7 G
*$ X, _; q _( x' H( e8 Q3 L- C
*/
c: N% a- X* J2 i7 H public class SkipSpaceOutputStream extends FilterOutputStream { }# x3 j' }/ z4 N
public SkipSpaceOutputStream(OutputStream out) {
7 e4 C$ x* \5 x% c super(out);0 s7 T1 V) q5 ?+ Q9 P
}/**
7 c' y# h0 w* V) o$ B * Rewrite the method in the parent class, and
2 h' h q$ W# N. Y9 X; N5 n' A * skip the space character.3 {1 m3 m' m" d% r" x
*/* w% W4 n+ l0 e6 g. ?3 L
public void write(int b) throws IOException{
" Y( H s$ T! ]: N# v z if(b!=’ ’){; i. Q* z5 t9 S( w* ?
9 m! \# L/ \1 I( v' p
super.write(b); |