2-Java IO与装饰模式

来源:互联网 发布:淘宝骗术大全 编辑:程序博客网 时间:2024/06/12 05:17

1.Java IO分类
节点流-过滤流
输入流-输出流
字节流-字符流

2.InputStream,节点输入字节流的祖宗,抽象类
read():留给子类实现

public abstract int read() throws IOException;

read(byte b[]):0偏移,塞满数组b

public int read(byte b[]) throws IOException {    return read(b, 0, b.length);}

read(byte b[], int off, int len):可以看到,其实就是一个字节一个字节地读取,塞入字节数组b

public int read(byte b[], int off, int len) throws IOException {    if (b == null) {        throw new NullPointerException();    } else if (off < 0 || len < 0 || len > b.length - off) {        throw new IndexOutOfBoundsException();    } else if (len == 0) {        return 0;    }    int c = read();    if (c == -1) {        return -1;    }    b[off] = (byte)c;    int i = 1;    try {        for (; i < len ; i++) {            c = read();            if (c == -1) {                break;            }            b[off + i] = (byte)c;        }    } catch (IOException ee) {    }    return i;}

3.FileInputStream,节点流,继承自InputStream
read():native搞起

public int read() throws IOException {    return read0();}private native int read0() throws IOException;

read(byte b[]):还是native

public int read(byte b[]) throws IOException {    return readBytes(b, 0, b.length);}private native int readBytes(byte b[], int off, int len) throws IOException;

read(byte b[], int off, int len):native

public int read(byte b[], int off, int len) throws IOException {    return readBytes(b, off, len);}private native int readBytes(byte b[], int off, int len) throws IOException;

4.DataInputStream,过滤流,继承FilterInputStream实现DataInput
read(byte b[]):
这个in是个InputStream的引用,这就是装饰模式;
那么,这个in是什么时候进来的呢,是在DataInputStream的构造方法里进来的

public final int read(byte b[]) throws IOException {    return in.read(b, 0, b.length);}

read(byte b[], int off, int len):

public final int read(byte b[], int off, int len) throws IOException {    return in.read(b, off, len);}

readInt():

public final int readInt() throws IOException {    int ch1 = in.read();    int ch2 = in.read();    int ch3 = in.read();    int ch4 = in.read();    if ((ch1 | ch2 | ch3 | ch4) < 0)        throw new EOFException();    return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));}

5.装饰模式
InputStream:被装饰者
FileInputStream:具体被装饰者
FilterInputStream:装饰者
DataInputStream:具体装饰者
关系:
abstract class InputStream
FileInputStream extends InputStream
FilterInputStream extends InputStream
DataInputStream extends FilterInputStream implements DataInput

6.半透明装饰
首先,说一说透明装饰,或者说理想的装饰模式,那当然是具体装饰者的方法集合,不要超出被装饰者的;这样的话,当我们在业务方法中调用装饰者(往往是接口或者抽象类的一个引用)方法时,就不用担心转型问题;说道这里可能还是很迷糊,那么说个例子,PushbackInputStream。
PushbackInputStream extends FilterInputStream

先看下常规使用装饰模式:

public Client{    private InputStream in;    public Client(InputStream in){        this.in = in;    }    ......    public void read(byte[] b){        in.read(b, 0, b.length);    }}Socket socket = ...;byte[] b = ...;Client client = new Client(socket.getInputStream());client.read(b);

那么上面这个是ok的,不会有什么问题。
然后,这个时候由于我知道PushbackInputStream这个类,完了我还想用它提供的unread方法。

public Client2{    private InputStream in;    public Client2(InputStream in){        this.in = in;    }    ......    public void unread(int b){        in.unread(b);    }}Socket socket = ...;int b = ...;Client2 client2 = new Client2(new PushbackInputStream(socket.getInputStream()));client2.unread(b);

那么,这个时候就有问题了,因为unread这个方法是PushbackInputStream(可以认为是个具体装饰者)特有的,InputStream里压根没有。那么Client2的这个unread方法是有问题的,他需要改成这样:

public void unread(int b){    ((PushbackInputStream)in).unread(b);}

那么,说到这个半透明装饰,倒不能说是PushbackInputStream不好,毕竟人家提供额外的unread方法,只是我们自己使用的时候需要注意到这个点。

原创粉丝点击