Java 基础之IO总览

背景

IO在一般业务开发中不常用到,因此也是很久没有对这部分进行一次系统性的总结,最近有时间也是总结一下。

Java IO总览

Java IO这里指的传统IO,NIO会放到其他文章中介绍。在分类之前先了解一些概念。

流是一种对数据传递的抽象概念。比如,我们通过输入流读取磁盘上读取数据,就像水流一样连续源源不断流向用户态内存中。但是本质并非如此,至少不像水流那样源源不断,因为用户开发的程序运行在用户空间,而用户空间的进程是没有直接操作I/O设备的权限,需要内核进程帮忙操作I/O设备,用户空间进程会交出执行权,这个状态叫陷入内核,而用户空间的进程则表现为阻塞状态,等到需要读取的数据被内核进程准备好后,用户空间进程重新获得执行权,继续运行。

字节流

字节流和它的名字一样,是以字节的方式来操作文件的,这里的文件包括图片、视频、文本等,它的使用范围比字符流广泛,并且后面我们会介绍某些字符流如FilerReader也是建立在字节流上操作的,利用StreamDecoder按照编码方式将字节转换成字符,后面会详细介绍。字节流操作的byte。

字节流IO包中类继承关系如下

ALt

字符流

字符流操作的char

字符流IO包中类继承关系如下

Alt

输入流和输出流

  • 输入流:从文件读取到内存,只能进行读操作。
  • 输出流:从内存写入文件中,只能进行写操作。

节点流和处理流

  • 节点流:可以从或向一个特定的地方(节点)读写数据,说的有点抽象,把特定的地方理解为磁盘,内存或者其他设备就可以了。如FileReader
  • 处理流:可以对已存在的流进行连接和封装,如BufferedReader提供了一个缓冲区来操作已存在的输入字符流。

IO流的分类

从前文中两个流继承关系可以看到IO包中的继承关系非常复杂,要想靠这个继承关系搞清楚很难。我们要通过前文介绍的几个概念来对IO流作一个分类。

  • 按照操作方式分类,如图

    Alt

    各个流的简要说明:

    • FileInputStream:文件字节输入流,以字节方式读取
    • FileReader:文件字符输入流,以字符方式读取
    • FileOutputStream:文件字节输出流,以字节方式输出
    • FileWriter:文件字符输出流,以字符放松输出
    • CharArrayReader、StringReader:两种介质流,分别从char[]数组、String中读取数据
    • PipedReader、PipedWriter:分别代表管道字符输入流、输出流
    • BufferedReader、BufferedWriter:分别代表缓冲字符输入流、输出流
    • CharArrayWriter、StringWriter:写入char[]数组、写入String
    • BufferedInputStream、BufferedOutputStream:分别代表缓冲字节输入流、输出流
    • PipedInputStream、PipedOutputStream:分别代表管道字节输入流、输出流
    • ObjectInputStream、ObjectOutputStream:对象序列化输入流、输出流,属于处理流
    • DataInputStream、DataOutputStream:提供基础数据类型读取和写入操作
    • PrintStream、PrintWriter:打印流,是一种输出流

    通过上面的图可以看出,在很多操作都是成对出现的,比如File,就有FileReader、FileWriter、FileInputStream、FileOutPutStream。还有如Pipe、Array、Buffer。所以可以根据流的操作对象分类。

  • 按照流操作对象分类,如图,左边的是处理流,右边是节点流

    Alt

这么多流看的眼花缭乱,可想java io的设计者花费的心血。在后续章节中将详细介绍各种流的使用。