天天看點

java的io庫用到的裝飾模式是如何展現的?

概論

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

繼續閱讀