简介

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在干活

InputStreamReader的构造方法本质上只有一种那就是设置InputStream,这个被适配的对象
另外可选的设置编码,如果不设置使用系统默认的
设置系统编码的形式有:
使用给定字符集 和 使用给定字符集解码器 两种
构造方法中,都无一例外的设置了sd
他是StreamDecoder, decode也就是解码(read 从字节流读取成为字符,解码)
再回头仔细看下方法的代码,你会发现
InputStreamReader的所有方法只有两种类型,就仅仅做了两件事情
所有的构造方法设置了内部的StreamDecoder sd的值
剩下的所有的方法都是无差别的转发到sd中
所以说,根本的解码是StreamDecoder
 

StreamDecoder到底是什么呢?

StreamDecoder继承了Reader,所以他是一个Reader
另外他内部又包含了一个InputStream in;
这个in 通过他的forInputStreamReader系列方法,通过入参InputStream进行设置
StreamDecoder中提供的其他方法(除了forInputStreamReader系列)
又都依赖于内部的私有方法
这些私有方法又借助于InputStream
 
所以可以看得出来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
被适配者通过构造方法传递,属于适配器模式中的对象适配器
类似InputStreamReader ,他的构造方法也是涉及 被适配者OutputStream 以及字符编码

如果不设置使用系统默认的字符编码
设置系统编码的形式有:
使用给定字符集 和 使用给定字符集解码器 两种
 
内部有一个StreamEncoder se, encode  编码 如同我们前面介绍的那样
写入,是从字符,写入到二进制, 二进制序列才是真正的码,  那么也就是编码
所有的构造方法都共同做了初始化se这件事情
类似InputStreamReader   OutputStreamWriter所有的方法也只是做了两件事情
构造方法给se赋值
然后其他方法,无差别的转发请求到se
StreamEncoder的实现形式 类似StreamDecoder
他实现了Writer,并且内部维护了一个OutputStream
借助于forOutputStreamWrite系列方法对out进行设置
StreamEncoder 提供的方法

又都依赖于内部的私有的方法
这些私有方法又借助于OutputStream
比如
 

OutputStreamWriter小结

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

总结

InputStreamReader   和  OutputStreamWriter  是Reader  和 Writer的实现类
他们通过内部的StringDecoder 和 StringEncoder可以在字符流和字节流的处理过程中插入编码和解码的行为
 
转换流作为适配器的应用,只需要理解目标和被适配角色即可
目标就是在外面抛头露面,直接接触使用的形式
被适配角色就是幕后默默奉献的
也就是他们提供了Reader和Writer字符形式的读写操作方式
而内部则都是使用被适配角色,字节流的形式进行读写
中间涉及到的编码与解码 则依靠StreamEncoder 和StreamDecoder
 
转换流只需要理解记住他们的构造方法即可
然后你就可以当做什么都没发生,他就是一个Reader或者一个Writer
 
 
 

[十六]JavaIO之InputStreamReader 与 OutputStreamWriter的更多相关文章

  1. [二十六]JavaIO之再回首恍然(如梦? 大悟?)

    流分类回顾 本文是JavaIO告一段落的总结帖 希望对JavaIO做一个基础性的总结(不涉及NIO) 从实现的角度进行简单的介绍 下面的这两个表格,之前出现过 数据源形式 InputStream Ou ...

  2. Java-IO之InputStreamReader和OutputStreamWriter

    InputStreamReader和OutputStreamWriter是字节流通向字符流的桥梁.它使用指定的差染色体读写字节并将其解码为字符.InputStreamReader的作用是将字节输入流转 ...

  3. java基础知识回顾之javaIO类---InputStreamReader和OutputStreamWriter转化流

    InputStreamReader:是字节流通向字符流的桥梁: OutputStreamWriter 是字符流通向字节流的桥梁: package com.lp.ecjtu; import java.i ...

  4. Java IO(十六)InputStreamReader 和 InputStreamWriter

    Java IO(十六)InputStreamReader 和 InputStreamWriter 一.介绍 InputStreamReader 和 OutputStreamWriter 是字节流通向字 ...

  5. Java IO--字符流--InputStreamReader 和 OutputStreamWriter

    今天继续学习字符流的子类!!!! 先来熟悉一下适配器设计模式:(手写的,,嘿嘿) 因为据说InputStreamReader 和OutputStreamWriter采用了适配器模式(现在我还没能理解, ...

  6. 201771010126 王燕《面向对象程序设计(Java)》第十六周学习总结

    实验十六  线程技术 实验时间 2017-12-8 1.实验目的与要求 (1) 掌握线程概念: ‐多线程 是进程执行过中产生的多条线索. 是进程执行过中产生的多条线索. 是进程执行过中产生的多条线索. ...

  7. 马凯军201771010116《面向对象与程序设计Java》第十六周知识学习总结

    一:理论知识部分 1.线程的概念: 程序是一段静态的代码,它是应用程序执行的蓝 本. ‐进程是程序的一次动态执行,它对应了从代码加 载.执行至执行完毕的一个完整过程. 多线程是进程执行过程中产生的多条 ...

  8. 刘志梅201771010115.《面向对象程序设计(java)》第十六周学习总结

    实验十六  线程技术 实验时间 2017-12-8 1.实验目的与要求 (1)当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时,或者出现了在方法中没有捕获的异常时,线程将 ...

  9. 201871010111-刘佳华《面向对象程序设计(java)》第十六周学习总结

    学号-姓名<面向对象程序设计(java)>第十六周学习总结 实验十四  应用程序归档与线程初步 实验时间 2019-12-12 第一部分:理论知识总结 1.程序与进程的概念 ‐程序是一段静 ...

随机推荐

  1. lua 文件编译相关工具

    -- 编译一个代码文件 -- loadfile (lua_State *L, const char *filename); -- 将一个文件加载为lua代码块,仅编译不执行,返回值为编译后的 -- 代 ...

  2. vue 学习小记

    vue 中有 data() .computed.methods.beforeRouteLeave.created等 具体的: data():定义一些文件中需要用到的变量,data中带return,是使 ...

  3. Java for Andriod 第二周学习总结

    第四章 学习时遇到的问题或新知识点: 1. 构造方法.每个类至少有一个构造方法,且构造方法必须的名称必须与类名相同. 2. Varargs.允许方法拥有一个可变长度的参数列表. 3. 对象的内存分配. ...

  4. 读取Excel文件存储在实体类中

    1.Maven文件 <!--读取Excel的架包--> <dependency> <groupId>org.apache.poi</groupId> & ...

  5. 微信小程序开发-tabbar组件

    "tabBar": { "backgroundColor": "#303133", "color": "#ff ...

  6. [编译] 5、在Linux下搭建安卓APP的开发烧写环境(makefile版)—— 在Linux上用命令行+VIM开发安卓APP

    星期三, 19. 九月 2018 02:19上午 - BEAUTIFULZZZZ 0)前言 本文不讨论用IDE和文本编辑器开发的优劣,是基于以下两点考虑去尝试用命令行编译安卓APP的: 了解安卓APP ...

  7. 七种经典排序算法及Java实现

    排序算法稳定性表示两个值相同的元素在排序前后是否有位置变化.如果前后位置变化,则排序算法是不稳定的,否则是稳定的.稳定性的定义符合常理,两个值相同的元素无需再次交换位置,交换位置是做了一次无用功. 下 ...

  8. Atlas实现MySQL大表部署读写分离

    序章 Atlas是360团队弄出来的一套基于MySQL-Proxy基础之上的代理,修改了MySQL-Proxy的一些BUG,并且优化了很多东西.而且安装方便.配置的注释写的蛮详细的,都是中文.英文不好 ...

  9. Javascript高级编程学习笔记(57)—— 事件(1)事件流

    事件 JS与HTML的交互是通过事件实现的 而事件指的就是:文档或浏览器窗口特定的交互瞬间 可以通过侦听器来预定事件,以便在事件发生时执行相应的代码 这种模式也是设计模式中的观察者模式 事件流 有了事 ...

  10. [Swift]LeetCode8. 字符串转整数 (atoi) | String to Integer (atoi)

    Implement atoi which converts a string to an integer. The function first discards as many whitespace ...