输入/输出体系
处理流的用法
使用处理流的典型思路是,使用处理流来包装节点流,程序通过处理流来执行输入/输出功能,让节点流与底层IO设备、文件进行交互。
实际识别处理流非常简单,只要流的构造器参数不是一个物理节点,而是已经存在的流,它就一定是处理流。
所有节点流都是直接以物理IO节点作为构造器参数的。
使用PrintStream处理流来包装OutputStream的例子:
1 |
|
提示:由于PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应该包装成PrintStream后进行输出。
注意:
使用处理流包装了底层节点流后,关闭输入/输出资源时,只要关闭最上层的处理流即可,系统会自动关闭被该处理流包装的节点流。
##输入/输出体系
Java输入/输出流体系常用流分类
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
---|---|---|---|---|
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter |
访问字符串 | StringReader | StringWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
抽象基类 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
注意:
字节流的功能比字符流的功能强大,因为计算机的所有数据都是二进制的,但问题是,如果使用字节流来处理文本文件,需要使用合适的方式把字节转换成字符,增加了编程难度。所以一个规则是:如果进行输入输出的数是文本文件,则考虑使用字符流,如果是二进制内容,考虑字节流。
计算机的文件分类
计算机文件通常分为二进制文件和文本文件两类,所有能用记事本打开并且可以看到字符内容的文件都是文本文件,反之则是二进制文件。实际上,计算机里所有文件都是二进制文件,文本文件只是二进制的一种特例。当二进制的内容刚好能被正常解析成文本,该二进制文件就变成了文本文件。如果要看到正常的文本内容,则必须在打开文件时与保存文件时使用相同的字符集,Windows系统简体中文默认使用GBK字符集,Linux系统默认使用UTF-8字符集。
转换流
输入/输出体系提供了两个转换流InputStreamReader 、OutputStreamWriter,用于将字节流转换为字符流,一个将字节输入流转换为字符输入流,一个将字节输出流转换为字符输出流。
Java没有提供将字符流转换为字节流的类。
Java使用System.in代表标准输入,但这个标准输入流是InputStream类的实例,使用不方便,而且键盘输入都是文本内容,所以可以使用InputStreamReader将其转换为字符输入流,普通的Reader读取输入内容依然不太方便,可以将Reader再次包装成BufferedReader,利用BufferedReader的readLine()方法可以一次性读取一行。
如下程序:
1 |
|
推回输入流
有两个特殊的类,就是PushbackInputStream和PushbackReader,他们都提供了三个方法:
void unread(byte[]/char[] buf)
功能:将一个字节/字符数组推回到缓冲区里,从而允许重复读取内容。
参数:
- byte[]/char[] buf:需要推回的字节/字符数组;
返回值:无
void unread(byte[]/char[] buf, int off, int len)
功能:将一个字节/字符数组从off开始,长度为len字节/字符的内容推回到缓冲区里,从而允许重复读取内容。
参数:
- byte[]/char[] buf:需要推回的字节/字符数组;
- off:需要推回内容的开始位置;
- len:推回内容的长度
返回值:无
void unread(int b)
功能:将一个字节/字符推回到缓冲区里,从而允许重复读取内容。
参数:
- b:需要推回的字节/字符;
返回值:无
这两个推回输入流都带有一个推回缓冲区,当程序调用这两个推回输入流的unread()方法时,系统会把指定内容推回该缓冲区,而推回输入流每次调用read()方法时,总是先从推回缓冲区读取,只有完全读取了推回缓冲区的内容以后,才会从原输入流读取。
创建推回输入流实例需要指定缓冲区大小,默认缓冲区长度为1,如果推回缓冲区内容超过缓冲区大小,会引发异常。
下面程序找出程序的"new PushbackReader"字符串,找到后,程序打印目标字符串之前的内容。
1 |
|