Java IO 体系介绍
- 流式部分:字节流和字符流
- 非流式部分:流式部分的辅助,比如File、RandomAccessFile 等
- 与安全、操作系统相关工具类:比如 FileSystem、SerializablePermission 等
接下来介绍流式部分
1.字节流和字符流
Java提供面向字节流处理的输入输出抽象类:InputStream 和 OutputStream
也提供面向字符处理的输入输出抽象类:Reader 和 Writer
为什么要额外提供处理字符的流类呢?因为Java使用Unicode编码,每个字符占用两个字节
面向单字节的输入输出流类来操作字符的输入和输出不是太方便
2.流家族
Java流家族可谓庞大,而且还能通过流装饰器进行各种组合,这里把常用的流类整理如下
2.1 面向字节流的API
- 面向文件的API:FileInputStream 和 FileOutputStream
- 面向字节数组的API:ByteArrayInputStream 和 ByteArrayOutputStream
- 面向对象的API:ObjectInputStream 和 ObjectOutputStream
- 面向二进制数据的API:DataInputStream 和 DataOutputStream
- 面向管道流的API:PipedInputStream 和 PipedOutputStream
- 面向压缩文件流的API:ZipInputStream 和 ZipOutputStream
- 用于对流包装的装饰器API:FilterInputStream 和 FilterOutputStream
这里对流的装饰器进行说明,比如想使用 FileInputStream 读取一个文件数据,但又想使用缓冲区功能
那该怎么办呢,这时装饰器 FilterInputStream 就能发挥作用了,此处演示简单代码
public static void testBuffer() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("a.txt");
// 具有缓冲功能的输入流:BufferedInputStream
// 他正是装饰器 FilterInputStream 输入流的子类
// 这样就能把一个面向文件的输入流转换成具有缓冲功能的输入流
BufferedInputStream bufferStream = new BufferedInputStream(fis);
try {
// 读取单个字节
int oneByte;
while ((oneByte = bufferStream.read()) != -1) {
System.out.println(oneByte);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 流使用完之后要关闭
if (null != bufferStream) {
try {
bufferStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.2 面向字符流的API
- 面向文件的字符流API:FileReader 和 FileWriter
- 面向字符数组的字符流API:CharArrayReader 和 CharArrayWriter
- 面向字符串的字符流API:StringReader 和 StringWriter
- 具有缓冲功能的字符流API:BufferedReader 和 BufferedWriter
- 具有装饰器功能的字符流API:FilterReader 和 FilterWriter
- 面向管道的字符流API:PipedReader 和 PipedWriter
2.3 完整的流体系
(1)顶层接口设计
前面已经提到过,InputStream、OutputStream、Reader 和 Writer都是抽象类
但在这之上还有4个顶层接口,分别是 Closeable、Flushable、Readable 和 Appendable
它们分别定义 close()、flush()、read() 以及 append() 方法
前3个方法很容易理解,分别是 关闭流、刷新缓冲区、读取流,那么最后一个方法是干什么用的呢?
恰巧就是前面的流家族没有列出来的,想想 StringBuilder 的append功能,再去看下整个体系吧
2.4 字节流与字符流的桥梁
前面把最常用的字节流、字符流API都整理了,也简单说了下为什么Java会推出面向字符的流类
尽管是为了处理Unicode文本更加方便,但是以字节的形式操作流,读写速度明显更快
那么要以字节的形式操作字符,如何把字节和字符流连接起来呢,就是下面这两个API
InputStreamReader:允许把一个面向字节的输入流转换成面向字符的输入流
OutputStreamWriter:允许把一个面向字节的输出流转换成面向字符的输出流
3.Java IO 流总结
流式部分总结:两个对应、一个桥梁
两个对应分别指:输入与输出流的对应;字节流和字符流的对应;
一个桥梁指:字节流到字符流的桥梁