1. 输入流和输出流
    按照流的流向来分,可以分为输入流和输出流。
    > 输入流:只能从中读取数据,而不能向其写入数据。
    > 输出流:只能向其写入数据,而不能从中读取数据。
    此处的输入、输出涉及一个方向问题,对于如图 15.1 所示的数据流向,数据从内存到硬盘,通常
    称为输出流
    也就是说,这里的输入、输出都是从程序运行所在内存的角度来划分的。

    2. 字节流和字符流
    字节流和字符流的用法几乎完全一样,区别在于字节流和字符流所操作的数据单元不同 —
    字节流操作的数据单元是 8位的字节,而字符流操作的数据单元是 16 位的字符。
    字节流主要由 InputStream 和 OutputStream 作为基类,而字符流则主要由 Reader 和 Writer 作为基类。

    3. 节点流和处理流
    按照流的角色来分,可以分为节点流和处理流。
    可以从/向一个特定的 IO 设备(如磁盘、网络)读/写数据的流,称为节点流,节点流也被称为低级流(Low Level Stream)。图 15.3 显示了节点流示意图。
    从图 15.3 中可以看出,当使用节点流进行输入/输出时,程序直接连接到实际的数据源,和实际的输入/输出节点连接。
    处理流则用于对一个已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能。处理流
    也被称为高级流。图 15.4 显示了处理流示意图。

    image.pngimage.png

    InputStream/Reader: 所有输入流的基类,前者是字节输入流,后者是字符输入流。
    > OutputStream/Writer: 所有输出流的基类,前者是多节输出流,后者是字符输出流。

    使用 Java 的 IO 流执行输出时,不要忘记关闭输出流,关闭输出流除了可以保证流的物理资源被回收之外,可能还可以将输出流缓冲区中的数据 flush 到物理节点里(因为在执行 close()方法之前,自动执行输出流的 flusI()方法)。Java 的很多输出流默认都提供了缓冲功能,其实没有必要刻意去记忆哪些流有缓冲功能、哪些流没有,只要正常关闭所有的输出流即可保证程序正常。

    上面程序在输出字符串内容时,字符串内容的最后是\r\n,这是 Windows 平台的换行符,通
    过这种方式就可以让输出内容换行;如果是 UNIX/Linux/BSD 等平台,则使用\n 就作为换行符。

    两种序列化机制的对比

    实现 Serializable 接口 实现 Externalizable 接口
    系统自动存储必要信息 程序员决定存储哪些信息
    Java 内建支持,易于实现,只需实现该接口即可,无须任何代码支持 仅仅提供两个空方法,实现该接口必须为两个空方法提供实现
    性能略差 性能略好