概論
java的io包下大概有85個類,真複雜。其實不然這些類又可以分為以下四個部分。
輸入流 輸出流
位元組流 InputStream OutputStream
字元流 Reader Writer
簡單來說,這四部分的對應都是很整齊的,有FileInputStream就有FileOutputStream,有BufferedReader就有BufferedWriter。
為了簡便我們就以InputStream為例說說io庫中的設計模式------裝飾模式
這是我自己在讀<<HeadFirst 設計模式>>時做的學習筆記。或者大家可以直接去看HeadFirst。
現在我們看看io的具體類圖
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cGcq5CO5UjM2QTYlljY0EWMxUmZyYzX4AzNxgTM4EzLchDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.jpg)
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