输入输出(I/O)是指程序与外部设备或其他计算机进行交互的操作。几乎所有的程序都具有输入与输出操作,如从键盘上读取数据,从本地或网络上的文件读取数据或写入数据等。通过输入和输出操作可以从外界接收信息,或者是把信息传递给外界。
Java 把这些输入与输出操作用流(Stream)来实现,通过统一的接口来表示,从而使程序设计更为简单。
流(Stream)是指在计算机的输入输出操作中各部件之间的数据流动,按照数据的传输方向,流可分为输入流与输出流。
Java 语言里的流序列中的数据既可以是未经加工的原始二进制数据,也可以是经过一定编码处理后符合某种特定格式的数据。
在 Java 中,把不同类型的输入输出源抽象为流,其中输入和输出的数据称为数据流(Data Stream)。数据流是 Java 程序发送和接收数据的一个通道,数据流中包括输入流(Input Stream)和输出流(Output Stream)。
输入输出时相对程序来说的,输出流是往存储介质或数据通道(文件、键盘、网络等)写入数据,而输入流是从存储介质或数据通道中读取数据。
流式输入输出的特点是数据的获取和发送均沿数据序列顺序进行,一般来说有以下几点特性:
为了提高数据的传输效率,引入了缓冲流(Buffered Stream)的概念,即为一个流配备一个缓冲区(Buffer)。所谓缓冲区,就是专门用于传送数据的一块内存。
关于缓冲区的说明:
使用数据流来处理输入输出的目的是使程序的输入输出操作独立于相关设备,由于程序不需关注具体设备实现的细节(具体细节由系统处理),所以对于各种输入输出设备,只要针对流做处理即可,不需修改源程序,从而增强了程序的可移植性。
为了方便流的处理,Java 语言提供了 java.io 包,在该包中的每一个类都代表了一种特定的输入或输出流。为了使用这些流类,编程时需要引入这个包。
Java 提供了两种类型的输入输出流:
字节流(Byte Stream)每次读写 8 位二进制数,也称为二进制字节流或位流。字符流一次读写 16 位二进制数,并将其做一个字符而不是二进制位来处理。
需要注意的是,为满足字符的国际化表示,Java 语言的字符编码采用的是 16 位的 Unicode 码,而普通文本文件中采用的是 8 位 ASCII 码。
java.io 中类的层次结构如下图所示:
针对一些频繁的设备交互,Java 语言系统预定了 3 个可以直接使用的流对象,分别是:
在 Java 语言中使用字节流和字符流的步骤基本相同,以输入流为例,首先创建一个与数据源相关的流对象,然后利用流对象的方法从流输入数据,最后执行 close() 方法关闭流。