0
    在计算机中,无论是文本、图片、音频、还是视频,所有文件都是以二进制(字节)现实存在的,IO 流中正对字节的输入输出提供了一系列的流,统称为字节流。字节流是程序中最常用的流,根据数据的传输方向可将其分为字节输入流和字节输出流。在 JDK 中,提供了两个抽象类 InputStream 和 OutputStream,他们是字节流的顶级父类,所有的字节输入流都继承自 InputStream,所有的字节输出流都继承自 OutputStream。为了方便理解,可以把 InputStream 和 OutputStream 比作两根“水管”,如下所示。

    IMG_0981(20200605-155130).JPG
    从图中可以看出,InputSream 被看出一个输入管道,OutputStream 被看成一个输出管道,数据通过 InputStream 从源设备输入到程序,通过 OutputStream 从程序输出到目标设备,从而实现数据的传输。由此可见,IO 流中的输入输出都是相对于程序而言的。

    1.1、
    在 JDK 中,InputStream 和 OutputStream 提供了一系列与读取数据相关的方法,接下来先来了解一下 InputStream 的常用方法,如下表所示。

    方法名称 方法描述
    int read() 从输入流读取一个 8 位的字节,把它转换为 0~255 之间的整数,并返回这一整数
    int read(byte[] b) 从输入录读取若干字节,把它们保存到参数 b 指定的字节数组中,返回的照书表示读取字节的数目
    int read(byte[] b,int off,int len) 从输入流读取若干字节,把它们保存到参数 b 指定的字节数组中,off 指定字节数组开始保存数据的起始下标,len 表示读取的字节数目
    void close() 关闭此输入流并释放与该流关联的所有系统资源

    上表中列举了 InputStream 的 4 个常用方法。前 3 个 read()方法都是用来读取数据的,其中,第一个 read()方法是从输入流中逐个读入字节,而第二个和第三个 read()方法则将若干字节以字节数组的形式一次性读入,从而提高读数据的效率。在进行 IO 流操作时,当前 IO 流会占用一定的内存,由于系统资源宝贵,因此,在 IO 操作结束后,应该调用 close()方法关闭流,从而释放当前 IO 流所占的系统资源。

    1.2、
    与 InputStream 对应的是 OutputStream。OutputStream 是用于写数据的,因此 OutputStream 提供了一些与写数据有关的方法,如下表所示。

    方法名称 方法描述
    void write(int b) 向输出流写入一个字节
    void write(byte[] b) 把参数b指定的字节数组的所有字节写到输出流
    void write(byte[] b,int off,int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入输出流
    void flush() 刷新此输出流并强制写出所有缓冲的输出字节
    void close() 关闭此输出流并释放于此流相关的所有系统资源

    上表中列举了 OutputStream 类的 5 个常用方法。前 3 个是重载的 write()方法,都用于向输出流写入字节。其中,第一个方法逐个写入字节,后两个方法是将若干个字节以字节数组的形式一次性写入,从而提高写数据的效率。flush()方法用来将当前输出流缓冲区(通常是字节数组)中的数据强制写入目标设备,此过程成为刷新。close()方法是用来关闭流并释放与当前 IO 流相关的系统资源。

    2、
    InputStream 和 OutputStream 这两个类虽然提供了一系列和读写数据有关的方法,但是这两个类是抽象类,不能被实例化。因此,针对不同的功能,InputStream 和 OutputStream 提供了不同的子类,这些子类形成了一个体系结构,如下所示。

    7.1.1 字节流的概念 - 图2

    7.1.1 字节流的概念 - 图3