[四] JavaIO之类层次体系结构横向比对

 

IO家族类层次体系结构横向匹配

 
上一篇文章中主要介绍了JavaIO流家族的总体设计思路,简单回顾下
基本逻辑涉及数据源 流的方向,以及流的数据形式这三个部分的组合
按照流的数据形式和流的方向,组合而来了四你们族,分别是:
InputStream/OutputStream Reader/Writer
数据源与四你们族的组合构成了IO流的基本功能
数据源形式 InputStream OutputStream Reader Writer
ByteArray(字节数组) ByteArrayInputStream  ByteArrayOutputStream 
File(文件) FileInputStream  FileOutputStream  FileReader FileWriter 
Piped(管道) PipedInputStream  PipedOutputStream  PipedReader  PipedWriter 
Object(对象) ObjectInputStream  ObjectOutputStream 
String StringBufferInputStream  StringReader  StringWriter 
CharArray(字符数组) CharArrayReader  CharArrayWriter 
 
扩展功能基本经过装饰器模式实现
扩展功能点 InputStream OutputStream Reader Writer
Data(基本类型) DataInputStream   DataOutputStream 
Buffered(缓冲) BufferedInputStream  BufferedOutputStream  BufferedReader  BufferedWriter   
LineNumber(行号) LineNumberInputStream  LineNumberReader 
Pushback(回退) PushbackInputStream  PushbackReader 
Print(打印) PrintStream  PrintWriter
 
从上面的列表应该能够看得出来,对于IO体系中的主要的一些类和接口
咱们只须要明确两点,就可以更加深刻的了解他们
1.针对于各类数据源,四你们族的处理逻辑
2.扩展功能点的含义   
 
注意:
不少IO的成员并不操做磁盘上的文件
好比ByteArrayInputStream和ByteArrayOutputStream  接下来咱们还会详细的介绍到
他们并不直接操做持久化的数据(存储在磁盘上的),还有很多其余的也都不是的
他们跟IO有什么关系?为何他们要实现流的接口?
此处我想要提醒的是,
对于咱们程序设计语言来讲,IO 表示的是对数据的操纵,数据有读写
IO表明的是一类可读可写行为相似的事物,而不是指从磁盘上读取文件
为何不是有一个单纯的类去进行对于字节数组的操做呢,为何非要跟IO挂钩沾边?
首先,这并非不能够,
的确是能够构造一个跟IO体系结构不要紧的字节数组
来操纵类进行字节数组的读写
 
但是,他的行为显然跟IO很是的相似,在定义一套不一样的接口显然增长开发者使用成本
再者,无论从哪里读 ,自己也仍旧是输入输出的问题
并且,针对不一样的数据源提供一致性的接口,这也很是的符合面向接口的编程规范
因此,一句话,不要把IO狭隘地理解为操做磁盘上的文件.数据.
IO是输入与输出,是读与写的代名词
 
 

IO数据源应用

 
ByteArray(字节数组)
字节数组,毫无疑问,不会应用在字符家族里面
他应用于 ByteArrayInputStream   以及  ByteArrayOutputStream
他的内部包含一个 字节数组    byte buf[]
ByteArrayInputStream  以及  ByteArrayOutputStream  内部维护了一个byte buf[]
会将数据读取到这个字节数组(缓冲区)
或者将数据写入到这个字节数组(缓冲区)
他们维护的是这个内部的字节数组自己,并不会写入文件
这两个类本质就是操纵字节数组,提供对字节数组的读取与写入
它的本质如同文件同样,都是用来存储数据
只不过是数据存在于内存中而已
经过将数据封装到内部的字符数组中,能够提供IO一致性的接口
ByteArray  仅仅应用与字节流
 
image_5b95160b_320
 
 
File(文件)
 
前面说过,File 是最多见的一种数据形式
因此对IO提供针对文件的操做很是合理
咱们知道,全部的数据存储最终都是字节的形式
可是对于文件的操做又是如此的频繁和重要
因此,针对于字符的输入输出也提供了对应的处理
不过仍是那句话,最终文件都是字节形式存储,因此,对于字符文件,天然须要进行编码与解码
FilterReader每一次的读取都意味着一次解码
FilterWriter每一次的写入都意味着编码
既然是文件,咱们前面介绍过File类
File类的构造主要由路径名或者文件描述符
因此对于文件的输入输出相关的IO操做,天然能够经过  路径名  文件描述符  或者File 自己做为目标对象
也就是说构造函数的参数通常都是这三者之一
对于文件的操做是实实在在的操做文件自己
File 四你们族都有应用
 
Piped(管道)
管道的概念,不是来自于java io很早前就有此概念
含义很是明朗,就如同他的名字同样,管道,好像两个水管链接起来,造成一个通道
这个通道是直接链接的,并不会再跑到别的地方去弯弯绕
管道流的主要做用是能够进行两个线程间的通信
既然主要做用进行线程间的通信,他就是传输数据使用的
IN 字节数组缓存数据,OUT使用IN对象

image_5b95160b_3d02
管道在四你们族中都有应用
 
Object
ObjectInputStream 和 ObjectOutputStream 的做用是,对基本数据和对象进行序列化操做支持
ObjectOutputStream对象能提供对“基本数据或对象”的持久存储
ObjectInputStream,读取出这些“基本数据或对象”
只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能被ObjectInputStream/ObjectOutputStream所操做
序列化天然不可能就只有字符,因此Object仅仅针对字节家族
 
String
提供了对String类型的支持
reader读取到String
writer写入到StringBuffer
image_5b95160b_7ef7
StringBufferInputStream  已经不推荐使用了
因此,后续能够认为String仅仅支持字符家族
 
 
CharArray
相似ByteArray,也是提供对字符数组的支持
操纵内存数据
image_5b95160b_552f
字符数组仅仅支持字符家族
 
 
其实能够看得出来,只有File才是真正跟磁盘文件相关的
其余的数据源形式都是操做内存数据
 
 

IO扩展功能应用

 
 
Data(基本类型)
Data是对基本数据类型的支持
针对于DataOutputStream写出的数据文件
可使用DataInputStream进行读取
也就是说是一种特殊形式的文件
他们底层依赖的仍是字节流  经过继承FilterInputStream 和 FilterOutputStream
使用其中的InputStream in   以及  OutputStream out
这两个对象是经过构造方法传递进来的
 
Buffered(缓冲)
缓冲也就是为了减小读取的频率,设置一个缓冲区
缓冲的概念处处都是,因此缓冲应用于四你们族
 
LineNumber(行号)
LineNumber是针对输入的
因此存在于LineNumberInputStream和LineNumberReader
不过对于字节流的LineNumberInputStream 已经弃用
LineNumberReader是一个跟踪行号的缓冲字符输入流
也很显然,流都是顺序读取不能回退的,因此想要读取行号天然要借助于缓存
他的实现继承BufferedReader 也很好理解
 
Pushback
Pushback 回退,也就是读取了一个字符,而后再次把它放回到流中
因此是针对输入的
PushbackInputStream  PushbackReader
也是借助于内部的缓存

image_5b95160b_1857
 
Print(打印)
主要是为了提供数据打印的便利性
打印天然是针对于输出的
PrintStream  PrintWriter
 
本文从数据源以及扩展功能点的角度,再次分析了IO类库的总体设计
虽然上一篇文章中对于全部的基本功能点以及扩展功能点已经作了一个介绍
本文再次说起是为了着重强调,数据源与扩展功能点在类层次结构中涉及的重要性
只有完全明确了数据源以及扩展功能点的逻辑
才能完全理解整个IO类库架构设计
相关文章
相关标签/搜索