API文档说明:InputStreamReader类是从字节流到字符流的桥接器:它使用指定的字符集读取字节并将它们解码为字符。可以通过指定名称、明确指定或接受平台默认字符集来设定它所使用的字符集。每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节。 为了实现字节到字符的有效转换,可以从基础流中提取比满足当前读取操作所需的更多字节。为了更高效地操作,请考虑以InputStreamReader为基础,在BufferedReader中进行包装
其继承Reader类
public class InputStreamReader extends Reader {}
1)字节流到字符流的桥梁怎么理解?
1、计算机存储的单位是字节,如尽管txt文本中有中文汉字这样的字符,但是对计算机而言,其是字节形式存在的
2、字节流读取是单字节读取,但是不同字符集解码成字符需要不通过个数,因此字节流读取会报错
为了缓存从字节流中读取的字节,并通过字符集解码成字符返回,需要使用流来实现,这就是字符流的形式
4、InputStreamReader流就是起这个作用,实现从字节流到字符流的转换
2)使用指定的字符集读取字节并将它们解码为字符怎么理解?
字节本质是8个二进制位,且不同的字符集对同一字节解码后的字符结果是不同的,因此在读取字符时务必要指定合适的字符集,否则读取的内容会产生乱码
3)它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集怎么理解?
意味着InputStreamReader类有多个方法或者多个构造方法来设置字符集
4)每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节怎么理解?
read()方法会尝试尽量冲底层字节流中读取2个字符到字符缓冲区中,注意这里是尽量,若遇到文件最后字符,则就只能读取到1个字符,因此每次read()方法读取的字节数是不定的
5)为了实现字节到字符的有效转换,可以从基础流中提取比满足当前读取操作所需的更多字节,请考虑在BufferedReader中包装InputStreamReader
该话暂未理解,需要了解BufferedReader类后对比读取效率才可得出答案
1)使用默认的字符集构造InputStreamReader流:本质是初始化其实例域的一个变量,并未看到任何关于字符集的设置
public InputStreamReader(InputStream in) { super(in); try { sd = StreamDecoder.forInputStreamReader(in, this, (String)null); } catch (UnsupportedEncodingException e) { throw new Error(e); } }
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); }
3)sd变量:本质是StreamDecoder类的对象,InputStreamReader的构造方法就是在给此对象做初始化操作
private final StreamDecoder sd;
1、我们可以发现InputStreamReaderAPI类的所有API都是利用了sd变量的,因此可以看出InputStreamReader类的方法本质是调用StreamDecoder类方法
2、因此我们需要了解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(); }
1、FileReader类仅仅是InputStreamReader的简单衍生并未扩展任何功能
2、FileReader类读取数据实质是InputStreamReader类在读取,而InputStreamReader读取数据实际是StreamDecoder类读取
3、因此在使用字符输入流的时候实际是StreamDecoder类在发挥作用
以上是JAVA中InputStreamReader流怎麼建構的詳細內容。更多資訊請關注PHP中文網其他相關文章!