Java IO总结,字节流转字符流与流的关闭

    |     2015年5月19日   |   输入输出(IO)操作   |     0 条评论   |    2116

Java I/O 可以按方向分成输入 / 输出,按数据单位分成字节流和字符流。键盘 System.in 是字节输入流,要按行读成字符串,就需要 InputStreamReader 这座桥,再包 BufferedReader。

I/O 大量使用装饰模式:关掉最外层流时,会不会连带关掉被包装的流?会。下面用源码说明。

1355467587_4888

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总结,字节流转字符流与流的关闭
本文链接地址:https://ai.zhousir.top/?p=661
回复 取消