一直对java.io一知半解,每到用时便google下例子代码----拿来主义,已是我之痼疾。
这几日便得了闲,拿了JDK 5的Doc、Thinking In Java(4th)和大话设计模式, 对照着JDK 5的源代码
开始看,翻来覆去几回,稍稍有了点眉目,便就上来得瑟一回,记个笔记。
--------------------------------------------------------------------------------------------
一. 从InputStream 及其子类的结构入手
java.io中类数众多,名称相似,一眼看去,已是花了,至于哪些是输入相关的基本类,哪些又是装饰者类
就分不清了。所以我们就先来理一理其中的结构:
java.io中的类大致分为两个部分:
1. InputStream、OutputStream --- 是对字节序列进行操作的抽象类,由JDK1.0发布。
2. Reader、Writer --- 是基于Unicode Code Unit 进行操作的抽象类, 由JDK1.1发布。
我们今天先从InputStream入手,参考JDK文档画出了它的UML 类图(请从附件下载,图的篇幅较宽,就不贴了)。
图解 ---参考附件中图的左边部分(InputStream),右边是Reader:
1. 输入相关的抽象超类:java.io.InputStream
2. 输入相关的基本类:继承自java.io.InputStream,具体使用方法请参考JDK文档,但大致可以从其名字中看出其含义。总共有8个:
ByteArrayInputStream
PipedInputStream
SequenceInputStream
FileInputStream
ObjectInputStream
StringBufferInputStream(已经过时,由StringReader代替)
javax.sound.sampled.AudioInputStream(外部类)
org.omg.CORBA.portable.InputStream(外部类)
3. 装饰者超类:FilterInputStream,同样也继承自java.io.InputStream
4. 装饰者子类:继承自FilterInputStream,用于装饰上面的
"2. 输入相关的基本类",共有4个:
BufferedInputStream
PushbackInputStream
DataInputStream
LineNumberInputStream(已经过时)
二. InputStream 和 装饰者模式
众人皆知java的输入输出包"java.io"是一个装饰者模式的典型案例,这从下面这个代码就可以大致看出:
final BufferInputStream bin =
new BufferInputStream(new FileInputStream("C:\\test.log"));
但具体是怎样子的还是需要查看JDK源代码:
1. java.io.InputStream == 装饰者模式中的所有类(装饰者和被装饰者)的抽象超类
public abstract class InputStream implements Closeable {
// 定义抽象方法:read
public abstract int read() throws IOException;
}
2.java.io.FileInputStream == 具体的被装饰者对象
public class FileInputStream extends InputStream {
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
// 调用本地read方法
public native int read() throws IOException;
}
3.java.io.FilterInputStream == 装饰者对象的超类
public class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
protected FilterInputStream(InputStream in) {
this.in = in;
}
// 装饰者超类的read方法
public int read() throws IOException {
return in.read();
}
}
4.java.io.BufferedInputStream == 具体的装饰者对象
public class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream in) {
this(in, defaultBufferSize);
}
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
// 具体装饰者类的read方法
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
}
有过模式设计经验的同学不难发现这是一个经典的装饰者模式。
下一次,我们来看看InputStream和Reader的关系。