Java类库的设计者通过创建大量的类来解决I/O系统设计的难题。一开始,可能会对Java I/O系统提供了如此多的类感到不知所措(具有讽刺意味的是,Java I/O设计的初衷是为了避免过多的类) ——–《Thinking in Java》
介于Java I/O类库中数目众多的类,我们有必要清楚这个类库是如何设计的。
分类
Java1.0版本以前,Java中与输入有关的所有类都应该从InputStream这个抽象类继承,而与输出类有关的所有类都应当从OutputStream这个抽象类继承。但是,这种I/O流继承层次结构仅支持8位字节流,并不能很好的处理16位的Unicode字符。由于Unicode用于字符国际化(Java中的char也是16位的Unicode),所以在Java1.0以后添加了Reader和Writer继承层次结构,这样做就是为了在所有的I/O操作中都支持Unicode。
注意,在某些场合(例如音频/视频文件/压缩文件),面向字节的InputStream和OutputStream才是正确的解决方案。所以,最明智的做法是尽量尝试使用Reader和Writer,一旦程序无法成功编译,再使用面向字节的类库。
InputStream
此抽象类是表示字节输入流的所有类的超类。
InputStream抽象类的主要子类有:
- ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。即允许将内存的缓冲区当做InputStream使用
- FileInputStream 用于从文件中读取信息
- PipedInputStream 产生用于写入相关PipedOutputStream的数据,实现“管道化”概念
- SequenceInputStream 将两个或多个InputStream对象转换成单一InputStream
- FilterInputStream 抽象类,作为“装饰器”的接口。其中“装饰器”为其他的InputStream类提供有用功能。
注意:除了FilterInputStram类,InputStream类的其他子类都对应与一种数据源。例如:字节数组,文件等。而FilterInoutStream类的出现是因为Java在设计I/O系统时采用了“装饰器”设计模式。(关于装饰器设计模式请参看http://blog.csdn.net/jason0539/article/details/22713711)
OutputStream
此抽象类是表示输出字节流的所有类的超类。输出流接受输出字节并将这些字节发送到某个接收器。
OutputStream的一些子类:
- ByteArrayOutputStream 此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。即在内存中创建缓冲区,所有送往流的数据都要放置在此缓冲区。
- FileOutputStream 用于将信息写至文件
- PipedOutputStream 任何写入其中的信息都会自动作为相关PipedInputStream的输出,实现“管道化”概念。
- FilterOutputStream 抽象类,作为“装饰器”的接口,其中装饰器为其他OutputStream提供有用功能。
注意:除了FilterOutputStream 类,OutputStream类的其他子类都对应了输出所要去的目标。
FilterInputStream&FilterOutputStream
FilterInputStream和FilterOutputStream是用来提供装饰七类接口以控制特定输入流和输出流的两个类,这两个类是装饰器的必要条件(以便能为所有正在被修改的对象提供调用接口)。而两者的装饰器子类可以来修改“流”以满足某种特殊需要。
FilterInputStream的装饰器子类
- DataInputStream 与DataOutputStream搭配使用,因此我们可以按照可移植方式从流读取基本数据类型
- BufferedInputStream 使用它可以防止每次读取时都得进行实际写操作,代表使用缓冲区。
- PushbackInputStream 具有“能弹出一个字节的缓冲区”,因此可以将读到的最后一个字符回退。
FilterOutputStream的装饰器子类
- DataOutputStream 与DataInputStream 搭配使用,因此我们可以按照可移植方式向流中写入基本数据类型
- PrintStream 用于产生格式化输出。其中DataOutputStream处理数据的存储,PrintStream处理显示。
- BufferedOutputStream 使用它可以防止每次发送数据时都得进行实际写操作,代表使用缓冲区
Reader&Writer
注意:Reader和Writer的继承层次结构与InputStram和OutputStream的集成层次结构非常相似,可对照学习,这里不再详细阐述。
InoutStreamReader&OutputStreamWriter
又是我们必须把来自于“字节”层次结构中的类和“字符”层次结构中的类结合起来使用,为了实现这个目的,要用到适配器类:InoutStreamReader&OutputStreamWriter。InputStreamReader类可以把InputStream转换为Reader,OutputStreamReader类可以把OutputStream转换为Writer。
RandomAccessFile
这是一个自我独立的类,直接从Object类派生而来。与其他两个继承层次结构没有任何关系。可以实现在一个文件内向前,向后移动。
注意:
- 本篇博客是一篇读书笔记,具体内容请参看《Thinking in Java》第18章 Java I/O系统
- 本篇文章只讲述了Java I/O系统的设计框架,关于具体类的用法请参看其他博客。