Java采用了流的机制来实现输入/输出。所谓流,就是数据的有序排列。
而流可以是从某个源(称为流源或Source of Stream)出来,到某个目的地(称为流汇或Sink of Stream)去的。
由流的方向,可以分成输入流和输出流。一个程序从输入流读取数据向输出流写数据。
流处理器所处理的流必定都有流源,而如果将流类所处理的流源分类的话,基本可以分成两大类:
第一 数组,String,File等,这一种叫原始流源。
第二 同样类型的流用做链接流类的流源,叫链接流源。
Java语言的I/O库是对各种常见的流源,流汇以及处理过程的抽象化。
客户端的Java程序不必知道最终的流源,流汇是磁盘上的文件还是数组等;(原始流)
也不必关心数据是否经过缓冲的,可否按照行号读取等处理的细节。(链接流)
要理解Java I/O这个庞大而复杂的库,关键是要掌握两个对称性跟两个设计模式。
Java I/O库具有两个对称性,它们分别是:
1 输入-输出对称性:
比如InputStream和OutputStream各自占据Byte流的输入与输出的两个平行的等级结构的根部。
而Reader和Writer各自占据Char流的输入与输出的两个平行的等级结构的根部。
2 byte-char对称:
InputStream和Reader的子类分别负责Byte和Char流的输入;
OutputStream和Writer的子类分别负责Byte和Char流的输出,
它们分别形成平行的等级结构。
Java I/O库的两个设计模式:
装饰者模式(Decorator)
适配器模式(Adapter)
1 装饰者模式:
在由InputStream,OutputStream,Reader和Writer代表的等级结构内部,有一些流处理器可以对另一些流处理器起到装饰作用,形成新的,具有改善了的功能的流处理器。
【装饰者模式是Java I/O库的整体设计模式】
2 适配器模式:
在由InputStream,OutputStream,Reader和Writer代表的等级结构内部,有一些流处理器是对其它类型的流源的适配。
【适配器模式应用到了原始流处理器的设计上面,构成了I/O库所有流处理器的起点。】
装饰者模式的具体应用:
Java I/O库是由一些基本的原始流处理器和围绕它们的装饰流处理器所组成的。
InputStream类型中的装饰模式:
InputStream有七个直接的具体子类,和四个属于FilterInputStream的具体子类。
根据输入流的源的类型,可以将这些流类分成两种,
即原始流类(Original Stream)和链接流处理器(Wrapper Stream)。
原始流处理器:
接收一个Byte数组对象,String对象,FileDiscriptor对象或者不同类型的流源对象。
包括以下四种:
1)ByteArrayInputStream
2)FileInputStream
3)PipedInputStream
4)StringBufferInputStream
链接流处理器:
就是可以接收另一个流对象作为源,并对之进行功能扩展的类。
包括以下几种:
1)FilterInputStream,四个子类如下:
1.1)BufferedInputStream
1.2)DataInputStream
1.3)LineNumberInputStream
1.4)PushbackInputStream
2)ObjectInputStream
3)SeqcueneInputStream
装饰模式的使用目的:
链接流对象接收一个原始流对象或者另外一个链接流对象作为流源;
另一方面他们对流源的内部工作方法做了相应的改变。
适配器模式的具体应用:
FileInputStream是一个适配器类:
它继承了InputStrem类型,同时持有一个对FileDiscriptor的引用。
这是将一个FileDiscriptor对象适配成InputStrem类型的对象形式的适配器模式。
StringBufferInputStream是一个适配器类:
它继承了InputStream类型,同时持有一个对String对象的引用。
这是一个将String对象适配成InputStream类型的对象形式的适配器模式。
ByteArrayOutputStream是一个适配器类:
它继承了OutputStream类型,同时持有一个对byte数组的引用。
这是一个将byte数组的接口适配成OutputStream类型的接口的适配器模式。
FileOutputStream是一个适配器类:
它继承了OutputStream类型,同时持有一个对FileDiscriptor对象的引用。
这是一个将FileDiscriptor接口适配成OutputStream接口的适配器模式。
StringReader是一个适配器类:
它类继承了Reader类型,持有一个对String对象的引用。
这是一个将String的接口适配成Reader类型的接口的适配器模式。
InputStreamReader是一个适配器类:
它继承了Reader类型,同时持有一个对InputStream对象的引用。
InputStreamReader是从byte输入流到char输入流的一个适配器
OutputStreamWriter是适配器类:
。。。
OutputStringWriter是从OutputStream到Writer的适配器类
与任何一个OutputStream的具体子类相链接时,OutputStringWriter可以将OutputStream类型的byte流适配成为char流。
其他参考内容:
原始流处理器
1. ByteArrayInputStream:为多线程的通信提供缓冲区操作功能,接收一个Byte数组作为流的源。
2. FileInputStream:建立一个与文件有关的输入流。接收一个File对象作为流的源。
3. PipedInputStream:可以与PipedOutputStream配合使用,用于读入一个数据管道的数据,接收一个PipedOutputStream作为源。
4. StringBufferInputStream:将一个字符串缓冲区转换为一个输入流。接收一个String对象作为流的源。
(JDK帮助文档上说明:已过时。此类未能正确地将字符转换为字节。从JDK1.1开始,从字符串创建流的首选方法是通过StringReader类进行创建。只有字符串中每个字符的低八位可以由此类使用。)
链接流处理器:
1. FilterInputStream称为过滤输入流,它将另一个输入流作为流源。这个类的子类包括以下几种:
BufferedInputStream:用来从硬盘将数据读入到一个内存缓冲区中,并从缓冲区提供数据。
DataInputStream:提供基于多字节的读取方法,可以读取原始类型的数据。
LineNumberInputStream:提供带有行计数功能的过滤输入流。
PushbackInputStream:提供特殊的功能,可以将已经读取的字节“推回”到输入流中。
2. ObjectInputStream可以将使用ObjectInputStream串行化的原始数据类型和对象重新并行化。
3. SeqcueneInputStream可以将两个已有的输入流连接起来,形成一个输入流,从而将多个输入流排列构成一个输入流序列。
Java语言的I/O库提供InputStream,OutputStream,Reader,Writer四个系列的类。
InputStream和OutputStream处理8位字节流数据;Reader和Writer处理16位的字符流数据。
InputStream和Reader处理输入,OutputStream和Writer处理输出。
Java语言支持四种类型:Java接口,Java类,Java数组,原始类型(即int,float等)。
前三种是引用类型,类和数组的实例是对象,原始类型的值不是对象。
也即,Java语言的数组是像所有的其他对象一样的对象,而不管数组中所存储的元素类型是什么。