Java与模式 之 I/O库中的应用

1.简介

Java语言的I/O库是对各种常见的流源,流汇以及处理过程的抽象化.客户端的Java程序不必知道最终的流源,流汇是磁盘上的文件还是一个数组,或者是一个线程.

Java I/O库的两个对称性:
1.输入-输出对称:比如InputStream和OutputStream各自占据Byte流的输入输出两个平行等级结构的根部.
2.byte-char对称:InputSteam与Reader的子类分别负责Byte和Char流的输入.

Java I/O库的两个设计:
1.装饰模式:在由InputStream,OutputStream,Reader和Writer代表的等级结构内部,有一些流处理器可以对另一些流处理器起到装饰作用,形成新的,具有改善功能的流处理器.
2.适配器模式:在由InputStream,OutputStream,Reader和Writer代表的等级结构内部,有一些流处理器是对其他类型的流源的适配.

2.InputStream

2.1 结构

这里写图片描述

这里只展示最常用的一些流.上述中的所有类都叫做流处理器,这些流可分为两种,即原始流类和链接流处理器.

2.1.1 原始流处理器

原始流处理器接收一个Byte数组对象,String对象,FileDescriptor对象或者不同类型的流源对象,并生成一个InputStream类型的流对象.在这里原始流处理器包括如下:
ByteArrayInputStream:为多线程的通讯提供缓冲区操作功能.
FileInputStream:建立一个与文件相关的输入流.
StringBufferInputStream:将一个字符串缓冲区转换为一个输入流.

2.1.2 链接流处理器

所谓链接流处理器,就是一个接受另一个流对象作为流源,并对之进行功能扩展的类.其包括以下几种:
BufferInputStream:用来从硬盘将数据读入到一个内存缓冲区中,并从此缓冲区提供数据.
DataInputStream:提供基于多字节的读取方法,可以读取原始数据类型的数据.
LineNumberInputStream:提供带有行计数功能的过滤输入流.

2.1.3 抽象结构图

这里写图片描述

上面的流处理器图与装饰模式的结构图有着显而易见的相同之处.

2.装饰模式

在InputStream类中这些流处理器扮演的角色分别是:

抽象构件:由InputStream扮演.
具体构件:由ByteArrayInputStream,FileInputStream以及StringBufferInputStream等原始流处理器扮演.
抽象装饰:由FilterInputStream扮演.
具体装饰:有几个类扮演,分别是DataInputStream,BufferedInputStream以及不常用到了类LineNumberInputStream.

2.1 FilterInputStream

public
class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered.
     */
    protected volatile InputStream in;

    /**
     * Creates a <code>FilterInputStream</code>
     * by assigning the  argument <code>in</code>
     * to the field <code>this.in</code> so as
     * to remember it for later use.
     *
     * @param   in   the underlying input stream, or <code>null</code> if
     *          this instance is to be created without an underlying stream.
     */
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
public int read() throws IOException {
        return in.read();
    }

在抽象链接流FilterInputStream中包装类一个InputStream,read()方法调用的是包装类的read方法.

2.2 DataInputStream

public
class DataInputStream extends FilterInputStream implements DataInput {

    /**
     * Creates a DataInputStream that uses the specified
     * underlying InputStream.
     *
     * @param  in   the specified input stream
     */
    public DataInputStream(InputStream in) {
        super(in);
    }

    /**
     * working arrays initialized on demand by readUTF
     */
    private byte bytearr[] = new byte[80];
    private char chararr[] = new char[80];

 public final short readShort() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        if ((ch1 | ch2) < 0)
            throw new EOFException();
        return (short)((ch1 << 8) + (ch2 << 0));
    }

 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));
    }

该类是FilterInputStream的实现类,构造器通过super(in)进行装饰流对象,而一些其他方法如readShort和readInt是对原始流处理器的扩展.

3.适配器模式

Java I/O里面,有一个InputStreamReader类叫做桥梁类.
该类将读入的Byte数据根据指定编码翻译成char数据.它不是桥梁模式的应用,而是适配器模式的应用.

3.1 InputStreamReader例子

@Test
    public void inputStreamReader() 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对象的readLine()方法读取整行的输入数据,数据类型是String.
这个简单的例子涉及了两个设计模式.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值