[IO] JavaIO之InputStreamReader 与 OutputStreamWriter(十七)

编程语言 编程语言 7008 人阅读 | 0 人回复

简介

InputStreamReader OutputStreamWriter是转换流 InputStreamReader 是字节流通向字符流的桥梁,它将字节流转换为字符流. OutputStreamWriter是字符流通向字节流的桥梁,它将字符流转换为字节流. 适配器模式 Reader和Writer 是Target 被适配角色Adaptee是 InputStream / OutputStream 被适配者都是通过构造方法传递进来的,所以是对象适配器模式

编码与解码

经常说到编码和解码 也就是从字符到字节,或者字节到字符的转换,转换的规则就是按照指定的码表 有的时候可能会混淆,到底哪个方向才是编码?哪个才是解码?

只要理解了码的含义 指的是二进制的 0 1 的数值序列 编码表中都有字符对应的数值序列编码 把字符从符号转变成二进制序列就是编码 解码就是转换为指定的字符形式

字节流和字符流之间的转换,自然离不开编码与解码 计算机最底层数据的存储是二进制序列,也就是字节 所以如果是从最底层读取,那么就是涉及二进制到字符的解码 从字符写入到最底层,就是字符的编码

InputStreamReader

适配器模式下,InputStreamReader继承了Reader, 也看得出来Reader是目标 这个场景下的适配器,就是可以通过对InputStream调用Reader 相关的约定协议 也就是InputStream包装成了Reader,看起来用起来像是一个Reader,只不过底层内部是InputStream在工作

简言之,就是他就是一个Reader,他的行为方式也是Reader家族的,只不过里面有一个InputStream在干活

image.png

InputStreamReader的构造方法本质上只有一种那就是设置InputStream,这个被适配的对象 另外可选的设置编码,如果不设置使用系统默认的 设置系统编码的形式有: 使用给定字符集 和 使用给定字符集解码器 两种

构造方法中,都无一例外的设置了sd 他是StreamDecoder, decode也就是解码(read 从字节流读取成为字符,解码)

image.png

再回头仔细看下方法的代码,你会发现 InputStreamReader的所有方法只有两种类型,就仅仅做了两件事情 所有的构造方法设置了内部的StreamDecoder sd的值 剩下的所有的方法都是无差别的转发到sd中 所以说,根本的解码是StreamDecoder

image.png

StreamDecoder到底是什么呢?

StreamDecoder继承了Reader,所以他是一个Reader 另外他内部又包含了一个InputStream in; 这个in 通过他的forInputStreamReader系列方法,通过入参InputStream进行设置

image.png

StreamDecoder中提供的其他方法(除了forInputStreamReader系列) 又都依赖于内部的私有方法 这些私有方法又借助于InputStream

image.png

所以可以看得出来InputStreamReader只是一个外包公司,他的活都是转包给StreamDecoder的

InputStreamReader小结

内部借助StreamDecoder的实现过程作为了解 需要记住InputStreamReader 是一个转换流,用于把InputStream转换为Reader 也就是让一个InputStream能够以Reader的方式进行工作, InputStreamReader 继承了Reader,所以他是一个Reader 他是Reader的实现类,提供了Reader协议常规的读取方法以及配套方法 掌握了构造方法即可,其他方法语义同Reader中的约定

方法 说明
public int read() throws IOException 读取单个字符,返回读取到的字符串
public int read(char cbuf[], int offset, int length) 读取字符到指定数组cbuf[] ,从指定偏移量offset开始存储,读取length个
public boolean ready() true表示下一个read()方法保证不会阻塞
public void close() throws IOException

OutputStreamWriter

OutputStreamWriter 也是适配器模式 继承了Writer 是Writer 的 实现类 Writer是适配器模式的目标Target 被适配者Adaptee是OutputStream 被适配者通过构造方法传递,属于适配器模式中的对象适配器

image.png

类似InputStreamReader ,他的构造方法也是涉及 被适配者OutputStream 以及字符编码 如果不设置使用系统默认的字符编码 设置系统编码的形式有: 使用给定字符集 和 使用给定字符集解码器 两种

内部有一个StreamEncoder se, encode 编码 如同我们前面介绍的那样 写入,是从字符,写入到二进制, 二进制序列才是真正的码, 那么也就是编码 所有的构造方法都共同做了初始化se这件事情

image.png

类似InputStreamReader OutputStreamWriter所有的方法也只是做了两件事情 构造方法给se赋值 然后其他方法,无差别的转发请求到se

image.png

StreamEncoder的实现形式 类似StreamDecoder 他实现了Writer,并且内部维护了一个OutputStream 借助于forOutputStreamWrite系列方法对out进行设置

image.png

StreamEncoder 提供的方法 又都依赖于内部的私有的方法

这些私有方法又借助于OutputStream

比如

image.png

OutputStreamWriter小结

OutStreamWriter是字符流通向字节流的桥梁 OutStreamWriter的适配器模式以及内部调用StreamEncoder的流程形式,跟InputStreamReader 样式差不多 只需要了解清楚他的构造方法即可 提供的其他的write方法,遵循Writer的约定协议

总结

InputStreamReader 和 OutputStreamWriter 是Reader 和 Writer的实现类 他们通过内部的StringDecoder 和 StringEncoder可以在字符流和字节流的处理过程中插入编码和解码的行为

转换流作为适配器的应用,只需要理解目标和被适配角色即可 目标就是在外面抛头露面,直接接触使用的形式 被适配角色就是幕后默默奉献的 也就是他们提供了Reader和Writer字符形式的读写操作方式 而内部则都是使用被适配角色,字节流的形式进行读写 中间涉及到的编码与解码 则依靠StreamEncoder 和StreamDecoder

转换流只需要理解记住他们的构造方法即可 然后你就可以当做什么都没发生,他就是一个Reader或者一个Writer

common_log.png 转载务必注明出处:程序员潇然,疯狂的字节X,https://crazybytex.com/thread-153-1-1.html

关注下面的标签,发现更多相似文章

文章被以下专栏收录:

    黄小斜学Java

    疯狂的字节X

  • 目前专注于分享Java领域干货,公众号同步更新。原创以及收集整理,把最好的留下。
    包括但不限于JVM、计算机科学、算法、数据库、分布式、Spring全家桶、微服务、高并发、Docker容器、ELK、大数据等相关知识,一起进步,一起成长。
热门推荐
海康摄像头接入 wvp-GB28181-pro平台测试验
[md]### 简介 开箱即用的28181协议视频平台 `https://github.c
[CXX1300] CMake '3.18.1' was not
[md][CXX1300] CMake '3.18.1' was not found in SDK, PATH, or
[若依]微服务springcloud版新建增添加一个
[md]若依框架是一个比较出名的后台管理系统,有多个不同版本。