概论

java的io包下大概有85个类,真复杂。其实不然这些类又可以分为以下四个部分。

                    输入流                输出流


字节流         InputStream          OutputStream


字符流          Reader               Writer  


简单来说,这四部分的对应都是很整齐的,有FileInputStream就有FileOutputStream,有BufferedReader就有BufferedWriter。


为了简便我们就以InputStream为例说说io库中的设计模式------装饰模式


这是我自己在读<<HeadFirst 设计模式>>时做的学习笔记。或者大家可以直接去看HeadFirst。


现在我们看看io的具体类图


java的io库用到的装饰模式是如何体现的?_数据源


FileInputSteam,ByteArrayInputStream就是上面的各种"咖啡",是可以被包装的,前者从文件中读取数据,后者是从字节数组中读取数据。而FilterInputStream就是装饰类的基类,BufferedInputStream就是一个外壳,可以包裹之前所说的那些个"咖啡",它里面有一个InputStream的引用,


现在我说说FileInputSteam与BufferedInputStream


FileInputSteam,就是给文件这个数据源上装一个管道,读数据的时候,就是一个字节一个字节的读。如果把数据源想象成一个水库,使用FileInputSteam就是一滴水一滴水的从桶里取水。


BufferedInputStream它的作用就是在数据源上装一个"小桶"。以后取水的时候就是直接对这个小桶操作(桶首先会从数据源里装上水)。这样一来效率肯定高了。


具体的实现比较复杂,大家可以看看这个


​http://icanfly.iteye.com/blog/1207397​


别的几个装饰器也类似。



HeadFirst的例子

关于javaio中装饰模式的使用,我不想过多的将具体实现。现在咱们看一个来自HeadFirst的例子。将文件中的大写字面转换成小写字母。


import java.io.*;

public class LowerCaseInputStream extends FilterInputStream {

public LowerCaseInputStream(InputStream in) {
super(in);
}

public int read() throws IOException {
int c = super.read();
return (c == -1 ? c : Character.toLowerCase((char)c));
}

public int read(byte[] b, int offset, int len) throws IOException {
int result = super.read(b, offset, len);
for (int i = offset; i < offset+result; i++) {
b[i] = (byte)Character.toLowerCase((char)b[i]);
}
return result;
}
}

public class InputTest {
public static void main(String[] args) throws IOException {
int c;

try {
InputStream in =
new LowerCaseInputStream(
new BufferedInputStream(
new FileInputStream("test.txt")));

while((c = in.read()) >= 0) {
System.out.print((char)c);
}

in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}



那个test.txt文件里的内容是:asdfwwwwwEEEEEE


最后运行InputTest,输出的内容是asdfwwwwweeeeee