java 认识IO流

转载自 https://blog.csdn.net/japson_iot/article/details/79559719

标签: IO流


在讲完File类后,我们回到I/O流的框架

“流”的概念

我们最开始认识到:水流来表示水的传输,电流表示电的传输,人流表示…

流,是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO原理

IO流,也就是输入/输出流,用来处理设备之间的数据传输。Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。

java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。

这里面的输入和输出,读和写,都是站在程序的角度上来考虑,我即程序

  • 输入 input/Reader:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
  • 输出 output/Writer:将程序(内存)数据输出到磁盘、光盘等存储设备中

IO流分类

Java的IO流是一个大家族,共涉及40多个类。但实际上非常规则,都是从如下4个抽象基类派生的。

(抽象基类) 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

从分类上就将:

  • 按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流

在这里插入图片描述

下面进行详解

字节流

字节流以字节(8bit)为单位,能处理所有类型的数据(如图片、avi等)。

1. 输入字节流InputStream

下面,是以字节为单位的输入流的框架图。

在这里插入图片描述

从中,我们可以看出:

  • InputStream 是以字节为单位的输入流的超类。InputStream提供了read()接口从输入流中读取字节数据。

  • ByteArrayInputStream 是字节数组输入流。它包含一个内部缓冲区,该缓冲区包含从流中读取的字节;通俗点说,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来实现的。

  • PipedInputStream 是管道输入流,它和PipedOutputStream一起使用,能实现多线程间的管道通信。

  • FilterInputStream 是过滤输入流。它是DataInputStream和BufferedInputStream的超类。

  • DataInputStream 是数据输入流。它是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。

  • BufferedInputStream 是缓冲输入流。它的作用是为另一个输入流添加缓冲功能。

  • File 虽然在io包中定义,但是它的超类是Object,而不是InputStream。

  • FileDescriptor 是“文件描述符”。它可以被用来表示开放文件、开放套接字等。

  • FileInputStream 是文件输入流。它通常用于对文件进行读取操作。

  • ObjectInputStream 是对象输入流。它和ObjectOutputStream一起,用来提供对“基本数据或对象”的持久存储。

2. 字节输出流OutputStream

下面,是以字节为单位的输出流的框架图。

在这里插入图片描述

从中,我们可以看出。以字节为单位的输出流的公共父类是OutputStream:

  • OutputStream 是以字节为单位的输出流的超类。OutputStream提供了write()接口从输出流中读取字节数据。

  • ByteArrayOutputStream 是字节数组输出流。写入ByteArrayOutputStream的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

  • PipedOutputStream 是管道输出流,它和PipedInputStream一起使用,能实现多线程间的管道通信。

  • FilterOutputStream 是过滤输出流。它是DataOutputStream,BufferedOutputStream和PrintStream的超类。

  • DataOutputStream 是数据输出流。它是用来装饰其它输出流,它“允许应用程序以与机器无关方式向底层写入基本 Java 数据类型”。

  • BufferedOutputStream 是缓冲输出流。它的作用是为另一个输出流添加缓冲功能。

  • PrintStream 是打印输出流。它是用来装饰其它输出流,能为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

  • FileOutputStream 是文件输出流。它通常用于向文件进行写入操作。

  • ObjectOutputStream 是对象输出流。它和ObjectInputStream一起,用来提供对“基本数据或对象”的持久存储。

字符流

字符流以字符为单位,根据码表映射字符,一次可能读多个字节。字符流只能处理字符类型的数据。只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流

1. 字符输入流Reader

下面,是以字符为单位的输入流的框架图。

在这里插入图片描述

从中,我们可以看出。以字符为单位的输入流的公共父类是Reader:

  • Reader 是以字符为单位的输入流的超类。它提供了read()接口来取字符数据。

  • CharArrayReader 是字符数组输入流。它用于读取字符数组,它继承于Reader。操作的数据是以字符为单位!

  • PipedReader 是字符类型的管道输入流。它和PipedWriter一起是可以通过管道进行线程间的通讯。在使用管道通信时,必须将PipedWriter和PipedReader配套使用。

  • FilterReader 是字符类型的过滤输入流。

  • BufferedReader 是字符缓冲输入流。它的作用是为另一个输入流添加缓冲功能。

  • InputStreamReader 是字节转字符的输入流。它是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。

  • FileReader 是字符类型的文件输入流。它通常用于对文件进行读取操作。

2. 字符输出流Writer

下面,是以字符为单位的输出流的框架图。

在这里插入图片描述

从中,我们可以看出。以字符为单位的输入流的公共父类是Writer。

  • Writer 是以字符为单位的输出流的超类。它提供了write()接口往其中写入数据。

  • CharArrayWriter 是字符数组输出流。它用于读取字符数组,它继承于Writer。操作的数据是以字符为单位!

  • PipedWriter 是字符类型的管道输出流。它和PipedReader一起是可以通过管道进行线程间的通讯。在使用管道通信时,必须将PipedWriter和PipedWriter配套使用。

  • FilterWriter 是字符类型的过滤输出流。

  • BufferedWriter 是字符缓冲输出流。它的作用是为另一个输出流添加缓冲功能。

  • OutputStreamWriter 是字节转字符的输出流。它是字节流通向字符流的桥梁:它使用指定的 charset 将字节转换为字符并写入。

  • FileWriter 是字符类型的文件输出流。它通常用于对文件进行读取操作。

  • PrintWriter 是字符类型的打印输出流。它是用来装饰其它输出流,能为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

字节流转换为字符流

在java中,字节流能转换为字符流,下面是它们的转换关系图。

在这里插入图片描述

从中,我们可以看出。

  • FileReader继承于InputStreamReader,而InputStreamReader依赖于InputStream。具体表现在InputStreamReader的构造函数是以InputStream为参数。我们传入InputStream,在InputStreamReader内部通过转码,将字节转换成字符。

  • FileWriter继承于OutputStreamWriter,而OutputStreamWriter依赖于OutputStream。具体表现在OutputStreamWriter的构造函数是以OutputStream为参数。我们传入OutputStream,在OutputStreamWriter内部通过转码,将字节转换成字符。

节点流和处理流

节点流和处理流是两个流的概念:

  • 节点流可以从一个特定的数据源读写数据,直接作用在文件上

在这里插入图片描述

举个例子:

在这里插入图片描述

流的关闭顺序

  1. 一般情况下是:先打开的后关闭,后打开的先关闭
  2. 另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
  3. 可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法。

注意:

  1. 如果将节点流关闭以后再关闭处理流,会抛出IO异常。
  2. 如果关闭了处理流,再关闭与之相关的节点流,也可能出现IO异常。(hadoop编程文件流操作中遇到了。)

总结

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ted_cs/article/details/82785168