Java IO总结,字节流转字符流与流的关闭
周sir |
2015年5月19日 |
输入输出(IO)操作 |
0 条评论 | 2116
Java I/O 可以按方向分成输入 / 输出,按数据单位分成字节流和字符流。键盘 System.in 是字节输入流,要按行读成字符串,就需要 InputStreamReader 这座桥,再包 BufferedReader。
I/O 大量使用装饰模式:关掉最外层流时,会不会连带关掉被包装的流?会。下面用源码说明。

Java输入输出流
一、字节流转字符流
InputStreamReader 继承 Reader,是字节流通向字符流的桥梁。原文说明如下:
字节流转字符流使用类 InputStreamReader ,InputStreamReader 是字节流通向字符流的桥梁
从键盘读一行:数据来自字节流 System.in,一行又是字符串,所以要先转成字符流:
/**
* 实现从键盘读取一行数据功能。
*
* 读数据:输入流
* 一行的数据 == 字符串:字符流
* 键盘: System.in : 字节输入流
* InputStreamReader: 将字节流转换成字符流
*
* @throws IOException
*/
public void testInputStreamReader() throws IOException {
System.out.println("从键盘输入数据:");
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader buferReader = new BufferedReader(inputStreamReader);
String line = buferReader.readLine();
System.out.print("从键盘输入的数据是: \n" + line);
buferReader.close();
}
二、关掉最外层就会关掉里面
JAVA 的 IO 用了装饰模式。关闭最外面的流时,会自动调用被包装流的 close()。例如:
FileInputStream is = new FileInputStream(".");
BufferedInputStream bis = new BufferedInputStream(is);
bis.close();
BufferedInputStream 是 InputStream 的装饰类,给它加上缓冲。要关 is,只调最终装饰出来的对象的 close() 即可,因为它最终会调真正数据源的 close()。
JDK 里 BufferedReader.close() 就是这样写的:
public BufferedReader(Reader in, int sz) {
super(in);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.in = in;
cb = new char[sz];
nextChar = nChars = 0;
}
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
in.close();
in = null;
cb = null;
}
}
| 场景 |
怎么接 |
关闭 |
| 键盘读一行 |
System.in → InputStreamReader → BufferedReader |
关最外层 BufferedReader |
| 文件字节缓冲 |
FileInputStream → BufferedInputStream |
关 bis 即可,内层跟着关 |
三、一张图串起来
理解 Java IO 可对照下图:

一句话总结:字节流要当文本用就走 InputStreamReader 这座桥;流是一层层装饰的,close 最外层,里面的数据源会被一起关掉。
转载请注明来源:Java IO总结,字节流转字符流与流的关闭
我是周sir,这是我的博客。致力于分享我学会的技术和优秀的文章。微信公众号 “周sir专栏” 欢迎大家关注。