前言
I/O问题是整个人机交互的核心问题,同样Java提供了丰富的操作I/O的类,此处只讨论java.io包中的63个类(除去Exception类和Error类),根据数据格式和传输方式可以分成四类(平时可能使用最多的是字节流和字符流):
(1)基于字节操作的I/O接口:InputStream和OutputStream
(2)基于字符操作的I/O接口:Reader和Writer
(3)基于磁盘操作的I/O接口:File
(4)基于网络操作的I/O接口:Socket
1、基于字节的I/O操作接口
基于字节操作的I/O接口输入和输出分别是InputStream和OutputStream,InputStream的类层次结构如下所示(输入流根据数据类型和操作方式又被划分为若干个子类):
InputStream提供的主要方法:
public int read(byte b[], int off, int len) throws IOException;
OutputStream的类层次结构与InputStream的结构类似:
public void write(byte b[], int off, int len) throws IOException;
至于每个子类的具体操作方式和处理字节流的方式参考jdk1.8文档。
2、基于字符的I/O操作接口
在实际的磁盘操作或是网络操作中,操作的都是字节,而并不是字符,之所以有字符流之说是因为在实际程序中经常使用字符或者字符串,为了操作方便提供字符I/O接口。而不同的字符使用的编码不尽相同,这给在转换成字节时如果使用了不恰当的解码规则就会产生乱码,同时编解码本身也是一个耗时的操作。
基于字符操作的I/O接口输入和输出分别是Reader和Writer,Reader的类层次结构如下所示:
Reader提供的主要方法:
/**
* Reads characters into a portion of an array. This method will block
* until some input is available, an I/O error occurs, or the end of the
* stream is reached.
*
* @param cbuf Destination buffer
* @param off Offset at which to start storing characters
* @param len Maximum number of characters to read
* @return The number of characters read, or -1 if the end of the
* stream has been reached
*
* @exception IOException If an I/O error occurs
*/
abstract public int read(char cbuf[], int off, int len) throws IOException;
Writer的类层次结构与Reader的结构类似:
Writer提供的主要方法:
/**
* Writes a portion of an array of characters.
*
* @param cbuf Array of characters
* @param off Offset from which to start writing characters
* @param len Number of characters to write
* @throws IOException If an I/O error occurs
*/
abstract public void write(char cbuf[], int off, int len) throws IOException;
3、字节与字符的转化接口
数据持久化到磁盘或者在网络上传输的时候都是以字节形式处理的,Java针对字节与字符的转化提供了相应的接口:InputStreamReader和InputStreamWriter。InputStreamReader将字节流解码成字符,InputStreamWriter将字节流编码成字符,不管编码解码均须注意采用的字符集,两种转换均采用了适配器模式(通过InputStreamReader或者InputStreamWriter将InputStream适配成Reader或者Writer)。
字符解码过程(在StreamDecode中存在InputStream和Charset对象用于转化):
字符编码过程(StreamEncoder中存在OutputStream和Charset对象用于转化):