1. 输入流和输出流
按照流的流向来分,可以分为输入流和输出流。
> 输入流:只能从中读取数据,而不能向其写入数据。
> 输出流:只能向其写入数据,而不能从中读取数据。
此处的输入、输出涉及一个方向问题,对于如图 15.1 所示的数据流向,数据从内存到硬盘,通常
称为输出流
也就是说,这里的输入、输出都是从程序运行所在内存的角度来划分的。
2. 字节流和字符流
字节流和字符流的用法几乎完全一样,区别在于字节流和字符流所操作的数据单元不同 —
字节流操作的数据单元是 8位的字节,而字符流操作的数据单元是 16 位的字符。
字节流主要由 InputStream 和 OutputStream 作为基类,而字符流则主要由 Reader 和 Writer 作为基类。
3. 节点流和处理流
按照流的角色来分,可以分为节点流和处理流。
可以从/向一个特定的 IO 设备(如磁盘、网络)读/写数据的流,称为节点流,节点流也被称为低级流(Low Level Stream)。图 15.3 显示了节点流示意图。
从图 15.3 中可以看出,当使用节点流进行输入/输出时,程序直接连接到实际的数据源,和实际的输入/输出节点连接。
处理流则用于对一个已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能。处理流
也被称为高级流。图 15.4 显示了处理流示意图。
InputStream/Reader: 所有输入流的基类,前者是字节输入流,后者是字符输入流。
> OutputStream/Writer: 所有输出流的基类,前者是多节输出流,后者是字符输出流。
使用 Java 的 IO 流执行输出时,不要忘记关闭输出流,关闭输出流除了可以保证流的物理资源被回收之外,可能还可以将输出流缓冲区中的数据 flush 到物理节点里(因为在执行 close()方法之前,自动执行输出流的 flusI()方法)。Java 的很多输出流默认都提供了缓冲功能,其实没有必要刻意去记忆哪些流有缓冲功能、哪些流没有,只要正常关闭所有的输出流即可保证程序正常。
上面程序在输出字符串内容时,字符串内容的最后是\r\n,这是 Windows 平台的换行符,通
过这种方式就可以让输出内容换行;如果是 UNIX/Linux/BSD 等平台,则使用\n 就作为换行符。
两种序列化机制的对比
实现 Serializable 接口 | 实现 Externalizable 接口 |
---|---|
系统自动存储必要信息 | 程序员决定存储哪些信息 |
Java 内建支持,易于实现,只需实现该接口即可,无须任何代码支持 | 仅仅提供两个空方法,实现该接口必须为两个空方法提供实现 |
性能略差 | 性能略好 |