您的位置:首页 > 编程语言 > Java开发

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

2015-11-27 16:05 323 查看

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.

这个简单的例子涉及了两个设计模式.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: