JAVA基础知识之InputStreamReader流

2 篇文章 0 订阅

作者:咕噜是个大胖子
来源:CSDN
原文:https

1.InputStreamReader类

API文档说明:InputStreamReader类是从字节流到字符流的桥接器:它使用指定的字符集读取字节并将它们解码为字符。 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节。 为了实现字节到字符的有效转换,可以从基础流中提取比满足当前读取操作所需的更多字节。为了获得最高效率,请考虑在BufferedReader中包装InputStreamReader
其继承Reader类

public class InputStreamReader extends Reader {}

1.1 字节流到字符流的桥梁怎么理解?

  1. 计算机存储的单位是字节,如尽管txt文本中有中文汉字这样的字符,但是对计算机而言,其是字节形式存在的

  2. 字节流读取是单字节读取,但是不同字符集解码成字符需要不通过个数,因此字节流读取会报错

  3. 那么就需要一个流把字节流读取的字节进行缓冲而后在通过字符集解码成字符返回,因而形式上看是字符流

  4. InputStreamReader流就是起这个作用,实现从字节流到字符流的转换

1.2 使用指定的字符集读取字节并将它们解码为字符怎么理解

字节本质是8个二进制位,且不同的字符集对同一字节解码后的字符结果是不同的,因此在读取字符时务必要指定合适的字符集,否则读取的内容会产生乱码

1.3 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集怎么理解?

意味着InputStreamReader类有多个方法或者多个构造方法来设置字符集

1.4 每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节怎么理解

read()方法会尝试尽量冲底层字节流中读取2个字符到字符缓冲区中,注意这里是尽量,若遇到文件最后字符,则就只能读取到1个字符,因此每次read()方法读取的字节数是不定的

1.5 为了实现字节到字符的有效转换,可以从基础流中提取比满足当前读取操作所需的更多字节,请考虑在BufferedReader中包装InputStreamReader

该话暂未理解,需要了解BufferedReader类后对比读取效率才可得出答案

2.InputStreamReader构造方法

2.1 使用默认的字符集构造InputStreamReader流:本质是初始化其实例域的一个变量,并未看到任何关于字符集的设置

public InputStreamReader(InputStream in) {
           super(in);
           try {
               sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
           } catch (UnsupportedEncodingException e) {
              
               throw new Error(e);
           }
       }

2.2 使用指定的字符集名称构造InputStreamReader流:本质是初始化其实例域的一个变量,可以发现字符集是初始化方法的第三个参数

   public InputStreamReader(InputStream in, String charsetName)
            throws UnsupportedEncodingException
        {
            super(in);
            if (charsetName == null)
                throw new NullPointerException("charsetName");
            sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
        }

2.3 sd变量:本质是StreamDecoder类的对象,InputStreamReader的构造方法就是在给此对象做初始化操作

private final StreamDecoder sd;

3. InputStreamReaderAPI

我们可以发现InputStreamReaderAPI类的所有API都是利用了sd变量的,因此可以看出InputStreamReader类的方法本质是调用StreamDecoder类方法,因此我们需要了解StreamDecoder类,以便了解到InputStreamReader类的方法是如何起实质性作用的

        /**
         * 获取设置的字符集
         */
        public String getEncoding() {
            return sd.getEncoding();
        }
     
        /**
         * 读取流并返回一个字符,遇到文件末尾返回-1
         */
        public int read() throws IOException {
            return sd.read();
        }
     
        /**
         * 读取字符到字符数组的部分中,遇到文件末尾返回-1
         */
        public int read(char cbuf[], int offset, int length) throws IOException {
            return sd.read(cbuf, offset, length);
        }
     
        /**
         * 检测流是否准备好呗读取
         */
        public boolean ready() throws IOException {
            return sd.ready();
        }
     
        /**
        * 关闭流并释放资源
        */
        public void close() throws IOException {
            sd.close();
        }

4. InputStreamReader类与FileReader类关系

  1. FileReader类仅仅是InputStreamReader的简单衍生并未扩展任何功能

  2. FileReader类读取数据实质是InputStreamReader类在读取,而InputStreamReader读取数据实际是StreamDecoder类读取

  3. 因此在使用字符输入流的时候实际是StreamDecoder类在发挥作用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值