输入/输出流
在程序开发过程中,将输入与输出设备之间的数据传递抽象为流,例如键盘可以输入数据,显示器可以显示键盘输入的数据等。按照不同的分类方式,可以将流分为不同的类型:根据操作流的数据单元,可以将流分为字节流(操作的数据单元是一个字节)和字符流(操作的数据单元是两个字节或一个字符,因为一个字符占两个字节);根据流的流向,可以将流分为输入流和输出流。
从内存的角度出发:输入是指数据从数据源(如文件、压缩包或者视频等)流入内存中的过程,输入示意图如图15.1所示;输出是指数据从内存流出到数据源中的过程,输出示意图如图15.2所示。


输入流被用来读取数据,输出流被用来写入数据。 |
Java 语言定义了许多类专门负责各种方式的输入/输出,这些类都被放在 java.io 包中。其中,所有输入流类都是抽象类 InputStream(字节输入流)或抽象类 Reader(字符输入流)的子类,而所有输出流都是抽象类 OutputStream(字节输出流)或抽象类 Writer(字符输出流)的子类。
InputStream字节/Reader字符输入流
InputStream 类是字节输入流的抽象类,它是所有字节输入流的父类。InputStream 类的具体层次结构如图15.3所示。

该类中所有方法遇到错误时都会引发 IOException 异常。下面是对该类中的一些方法的简要说明。
-
read() 方法:从输入流中读取数据的下一个字节。返回 0~255 的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值为 −1。
-
read(byte[] b):从输入流中读取一定长度的字节,并以整数的形式返回字节数。
-
mark(int readlimit) 方法:在输入流的当前位置放置一个标记,readlimit 参数告知此输入流在标记位置失效之前允许读取的字节数。
-
reset() 方法:将输入指针返回当前所做的标记处。
-
skip(long n) 方法:跳过输入流上的 n 个字节并返回实际跳过的字节数。
-
markSupported() 方法:如果当前流支持 mark()/reset() 操作,就返回 true。
-
close 方法:关闭此输入流并释放与该流关联的所有系统资源。
并不是所有的 InputStream 类的子类都支持 InputStream 类中定义的所有方法,如 skip()、mark()、reset() 等方法只对某些子类有用。 |
Java 中的字符是 Unicode 编码的,并且是双字节的。InputStream 类是用来处理字节的,并不适合处理字符文本。Java 为字符文本的输入专门提供了一套单独的类,即 Reader 类,但 Reader 类并不是 InputStream 类的替换者,只是在处理字符串时简化了编程。Reader 类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。Reader 类的具体层次结构如图15.4所示。
Reader 类中的方法与 InputStream 类中的方法类似,读者在需要时可查看 JDK 文档。

OutputStream字节/Writer字符输出流
OutputStream 类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。OutputStream 类的具体层次结构如图15.5所示。
OutputStream 类中的所有方法均返回 void,在遇到错误时会引发 IOException 异常。下面是对 OutputStream 类中的一些方法的简要说明。
-
write(int b) 方法:将指定的字节写入此输出流中。
-
write(byte[] b) 方法:将 b 个字节从指定的 byte 数组写入此输出流中。
-
write(byte[] b,int off,int len) 方法:将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流中。
-
flush() 方法:彻底完成输出并清空缓存区。
-
close() 方法:关闭输出流。
Writer 类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。Writer 类的层次结构如图15.6所示。

