博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java IO : 流,以及适配器模式的应用
阅读量:7041 次
发布时间:2019-06-28

本文共 5195 字,大约阅读时间需要 17 分钟。

hot3.png

Java IO : 流,以及适配器模式的应用

适配器其实是分为对象适配器和类适配器两种,两种的工作原理不太一样。

对象适配器是使用组合的方法,在Adapter中会保留一个原对象(Adaptee)的引用,适配器的实现就是讲Target中的方法委派给Adaptee对象来做,用Adaptee中的方法实现Target中的方法。

174204_doqi_1469576.png

这种类型的好处就是,Adpater只需要实现Target中的方法就好了。

与对象适配器不同的是,类适配器是通过类的继承来实现的。Adpater直接继承了Target和Adaptee中的所有方法,并进行改写,从而实现了Target中的方法。

174229_6Y52_1469576.png

以上摘自 http://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/adapter.html

以ByteArrayInputStream为例,ByteArrayInputStream是一个基于对象的适配器,如下所示,

publicclass ByteArrayInputStream extends InputStream {    /**     * An array of bytes that was provided     * by the creator of the stream.     */    protected byte buf[];    /**     * The index of the next character to read from the input stream buffer.     */    protected int pos;    protected int mark = 0;    protected int count;       public ByteArrayInputStream(byte buf[]) {        this.buf = buf;        this.pos = 0;        this.count = buf.length;    }    public ByteArrayInputStream(byte buf[], int offset, int length) {        this.buf = buf;        this.pos = offset;        this.count = Math.min(offset + length, buf.length);        this.mark = offset;    }    public synchronized int read() {        return (pos < count) ? (buf[pos++] & 0xff) : -1;    }      public synchronized int read(byte b[], int off, int len) {        if (b == null) {            throw new NullPointerException();        } else if (off < 0 || len < 0 || len > b.length - off) {            throw new IndexOutOfBoundsException();        }        if (pos >= count) {            return -1;        }        int avail = count - pos;        if (len > avail) {            len = avail;        }        if (len <= 0) {            return 0;        }        System.arraycopy(buf, pos, b, off, len);        pos += len;        return len;    }    public synchronized long skip(long n) {        long k = count - pos;        if (n < k) {            k = n < 0 ? 0 : n;        }        pos += k;        return k;    }    public synchronized int available() {        return count - pos;    }      public boolean markSupported() {        return true;    }    public void mark(int readAheadLimit) {        mark = pos;    }    public synchronized void reset() {        pos = mark;    }    public void close() throws IOException {    }}

ByteArrayInputStream 内部维护了一个 byte buf[] 数组,通过继承 InputStream 的方法适配了对 buf[]  的读取。

StringBufferInputStream继承了InputStream类型,同时持有一个对 String 对象的引用,将 String 对象适配成InputStream类型的对象的适配器模式。

从byte流到char流的适配

在java语言的标准库 java I/O 里面,有一个InputStreamReader类叫做桥梁(bridge)类。InputStreamReader是从byte流到char流的一个桥梁,它读入byte数据并根据指定的编码将之翻译成char数据。 InputStreamReader虽然叫“桥梁”,但它不爽桥梁模式,是适配器模式的应用。 InputStreamReader InputStreamReader是从byte输入流到char输入流的一个适配器。下图所示就是InputStreamReader 的结构

/** * An InputStreamReader is a bridge from byte streams to character streams: It * reads bytes and decodes them into characters using a specified {@link * java.nio.charset.Charset charset}.   */public class InputStreamReader extends Reader {    private final StreamDecoder sd;    public InputStreamReader(InputStream in) {        super(in);        try {            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object        } catch (UnsupportedEncodingException e) {            // The default encoding should always be available            throw new Error(e);        }    }    public InputStreamReader(InputStream in, String charsetName)        throws UnsupportedEncodingException    {        super(in);        if (charsetName == null)            throw new NullPointerException("charsetName");        sd = StreamDecoder.forInputStreamReader(in, this, charsetName);    }    public InputStreamReader(InputStream in, Charset cs) {        super(in);        if (cs == null)            throw new NullPointerException("charset");        sd = StreamDecoder.forInputStreamReader(in, this, cs);    }    public InputStreamReader(InputStream in, CharsetDecoder dec) {        super(in);        if (dec == null)            throw new NullPointerException("charset decoder");        sd = StreamDecoder.forInputStreamReader(in, this, dec);    }    public String getEncoding() {        return sd.getEncoding();    }    public int read() throws IOException {        return sd.read();    }    public int read(char cbuf[], int offset, int length) throws IOException {        return sd.read(cbuf, offset, length);    }    public boolean ready() throws IOException {        return sd.ready();    }    public void close() throws IOException {        sd.close();    }}

为了说明适配器类InputStreamReader是如何使用,请看下面例子。Echo类可以将控制台输入的任何字符串从新打印出来,源代码如下:

public class Echo {    public static void main(String[] args) throws IOException {        String line;        InputStreamReader input = new InputStreamReader(System.in);        System.out.println("Enter data and push enter:");        BufferedReader reader = new BufferedReader(input);        line = reader.readLine();        System.out.println("Data entered :" + line);    }}

可以看出,这个类接受一个类型为inputStream的System.in对象,将之适配成Reader类型,然后再使用 

BufferedReader类“装饰”它,将缓冲功能加上去。这样一来,就可以使用BufferedReader对象的readerLine() 方法读入整行的输入数据,数据类型是String。 

参考:https://my.oschina.net/gao0516/blog/136103

============END============

转载于:https://my.oschina.net/xinxingegeya/blog/1796408

你可能感兴趣的文章
MySQL Split 函数
查看>>
http的post请求和get请求
查看>>
python 异常处理
查看>>
我的友情链接
查看>>
Centos Development Tools 安装
查看>>
1.1.2 C++发展历程
查看>>
我的友情链接
查看>>
awk笔记
查看>>
apache使用.htaccess进行基于文件扩展名的访问控制
查看>>
Hystrix降级技术解析-Fallback
查看>>
Windows XP 禁用防火墙、系统升级、系统还原指南
查看>>
让你的电脑变成wifi
查看>>
xshell 隧道透传
查看>>
zabbix-server添加zabbix-proxy
查看>>
iostat命令找不到
查看>>
外观模式
查看>>
我的友情链接
查看>>
Angular2 AoT编译以及Rollup摇树优化
查看>>
ReactJS 学习资料汇总
查看>>
IIS权限应该怎么给?
查看>>