java reader类子类_java io --- Reader类
在前几篇文章中一直讲的都是InputStream,这是操作字节流的类,然而我们在程序中往往要从文件等stream中读取字符信息,如果只用InputStream能否读取字符信息呢?当然可以。但是这涉及到了一个编码和解码的问题,传输双方必须才用同一种编码方式才能正确接收,这就导致每次在传输时,传输方需要做这么几件事:
1)将需要传输的字符编码成指定字节
2)传输字节
接收方需要做这么几件事:
1)接收字节
2)将字节解码成对应的字符
我们看一下下面的例子:
我在对应目录有一个文件,这个文件是按照utf-8编码的,现在利用InputStream读取到一个byte数组中,如果我们想要读取到文件的内容,还需要继续转码成utf-8格式的字符串。
输出:
the length of bytes is 16
the content is 你好吗?
从上面的例子中,我们看到只有InputStream就能解决传输字符串的问题了,但是每次都要先读成byte字节,再进行转码,麻烦,能不能直接传字符呢?????
答案是:不能!!!
计算机只认识0和1,也就是byte,只能传输byte。
但是别人的博客都说Reader和Writer神马的能传啊?这是理解角度的不同,我就认为不能传字符,爱咋咋地!
好的,我现在就正式介绍这个“能”传字符的Reader(Writer类似,我就不说了)。
先用一个例子说明,如果我们直接用Reader读取文件,会是怎样的?
输出:the length is 5
char [0] is 你
char [1] is 好
char [2] is 吗
char [3] is ?
char [4] is
the content is 你好吗?
这样一来,是不是清爽了,也就是在你读取文件的时候,使用Reader可以直接指定解码方式,这样就可以直接读字符内容了。关于编码的问题,比较复杂,有兴趣的请参考网上其他内容,比如Java中的char,是两个字节,但是如果你的文件是utf-8,读取字符时可能就会出现问题,因为utf-8的字符是变长的,有的字符是一个字节,有的是两个,有的是三个。
不是说计算机只能传输字节么,为什么这里能直接读取字符了,好,下面我带大家深入剖析一下Reader类。
废话少说,先上类图:
Java几乎为每一个InputStream都设计了一个对应的Reader,比如如果你想直接读取文件里的字符,可以用FileReader来代替FileInputStream。BufferedReader也是一个装饰者模式的reader,接收一个Reader作为参数,从而对Reader提供缓存功能。
但是这众多的Reader中,却有一部分没什么用(个人观点),先从Reader的源码看起:
我这里只列出了Reader的两个灵魂函数,即read()和read(char cbuf[], int off, int len)
read()和InputStream中的read()相似,不过这里是只读取一个字符,而这个方法通过调用read(char cbuf[], int off, int len) 来实现,这个方法是抽象方法,Reader的子类通过实现这个方法达到读取不同介质的目的。
接下来就说说这个Reader家族中最重要的实现类,InputStreamReader类。
先看看这个类的结构:
接着还是先放部分代码上来。
从上面的代码可以看出,InputStreamReader有一个重要的域,就是这个
private finalStreamDecoder sd;
就是这个域帮助InputStreamReader解决了编码的问题。其实这个StreamDecoder 类也是Reader的子类,从后面的read()方法也能看出,InputStreamReader的read()其实就是这个sd的read()方法,在剖析StreamDecoder 之前,我们再看一眼InputStreamReader的构造方法。
InputStreamReader有四个构造函数,我这里只说前两个,第一个接收一个InputStream作为参数。第二个多了一个charsetName,这就是指定了编码方式,第一种为什么不指定?如果不指定就采用系统默认的编码方式。这在后面的StreamDecode的源码中马上就能看出来。
现在我们再看看StreamDecode的源码:
这个类的核心就是read()这个方法,由于这里直接操作InputStream进行read(),因此可以读取出2个字节,java中每两个字节转成一个字符。
这就是Reader可以读取字符的原因,只不过是利用InputStream先将字节读取出来,再按照一定的编码方式转码,因此这就是我前面所说的Reader也不能读取字符的原因,因为它只是读字节,转字符而言。
最后再说一说这个BufferedReader,和BufferedInputStream类似,它也是一个装饰者模式的类,接收一个Reader类,提供缓存功能。看看它的源码:
我们这里只研究它最简单的构造方法,它的构造函数接收一个Reader对象,并建立一个缓存,如果未指定缓存长度,就使用默认的长度。
BufferedReader的灵魂方法read()和BufferedInputStream的read()方法类似,都是采用了一个fill方法,可以参考 java io -- FilterInputStream 与 装饰者模式这篇文章。
如果没有数据就用fill去读取一块数据,放在缓存里,如果缓存里有数据,直接从缓存里读就OK了。
总结:这篇文章总结了Reader类的用法与原理,但是本文没有具体涉及java的编码问题,这是一个较大的话题,有兴趣的可以去网上参考其他文章。
java reader类子类_java io --- Reader类相关推荐
- java继承孙子类_Java:类与继承
Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态 这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相关 ...
- java 枚举的继承_java中枚举类可以被继承吗?
java 枚举类 java中,使用关键字enum来定义枚举类,枚举类是一个特殊的类,大部分功能和普通类是一样的,区别为: ● 枚举类继承了java.lang.Enum类,而不是默认的Object类.而 ...
- java web 初始化方法_Java Web(二) 类的初始化及初始化顺序
1. 问题点 最近在写单例模式的时候碰到了@Autiwired注解注入为NULL的情况,研究一番,发现是和类的初始化顺序有关.先抛出我的问题: //异步处理 public class AsyncMan ...
- java 类爆炸_Java 封装与类
一.面向对象编程 面向对象编程三大特性:封装.继承和多态. 类是实现封装的手段,是面向对象编程的基本单元. 封装隐藏了类的内部实现细节,暴露给外界可控的操作,提高数据的完整性和安全性,提高模块的可重用 ...
- java 日期格式常量_Java 日期格式类
Java格式 - Java日期格式类 Java 8有新的Date-Time API来处理日期和时间. 我们应该使用新的Java 8 Date-Time API来格式化和解析日期时间值. 如果我们正在编 ...
- java接口作为参数_JAVA:将类、抽象类、接口当成方法的参数传入
将类当成参数传入方法,其实就是将类的对象传入方法,如果是抽象类,其实就是将抽象类的子类的对象传入方法,如果是接口,其实就是将接口实现类的对象传入方法. 因为抽象类和接口是不能实例化成对象的,所以必须找 ...
- Java学习之子类(八):abstract类和abstract方法
在设计程序的时候,我们会经常使用abstract类,原因是,abstract类只关心操作,而不关心这些操作具体的实现细节 细节应当由抽象类的非抽象子类去实现,这些子类可以给出具体的实例,来完成程序功能 ...
- java random函数用法_JAVA的Random类的用法详解
Random类主要用来生成随机数,本文详解介绍了Random类的用法,希望能帮到大家. Random类 (java.util) Random类中实现的随机算法是伪随机,也就是有规则的随机.在进行随机时 ...
- 基于java洗浴中心管理系统_Java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- java字符流解析_Java IO(四):字符流详解
一.字符流 字节流提供了处理任何类型输入/输出操作的功能(因为对于计算机而言,一切都是0和1,只需把数据以字节形式表示就够了),但它们不可以直接操作Unicode字符,因为一个Unicode字符占用2 ...
最新文章
- android用户界面之菜单(Menu)教程实例汇总
- 【MyBatis】myBatis动态传入表名进行查询
- QT,C++多项式计算器—version3(厌倦CMD黑框框的走起!)
- ios微信小程序下拉刷新怎么配_为什么他的下拉刷新是个动画效果?
- [IE9] 开发IE9上的屏幕取词功能
- Win2003中apache2整合tomcat5和iis6
- angular的html引入js,在AngularJS中的文件夹中加载JavaScript和CSS文件
- python 的案例实战_python案例实战之一
- 信号扫描_微观世界扫描电子显微镜(SEM)
- 计算机组成原理综合题,2013计算机组成原理复习题.doc
- 一个OSPF的区域备份在手册里看到的
- 第二百三十二节,Bootstrap排版样式
- 私藏的google浏览器插件
- 零基础如何学习java?
- python win32转pdf 横版_.doc使用python转换为pdf
- 全面分析游戏限制多开原理
- web端实现类微信的语音播放效果
- Java动态性——反射机制学习笔记
- 【阅读笔记】Towards Personalized Federated Learning个性化联邦综述
- 如何给单片机烧录程序?
热门文章
- wifi抓包/苹果电脑mac book抓wifi sniffer packet
- 计算经纬度距离工具类
- Java代码发送post请求工具类
- 【论文阅读】2018-基于深度学习的网络流量分类及异常检测方法研究_王伟
- ZZULIOJ1026
- 科研计算机视觉常用绘图软件,科研图形处理——除了R、Graphpad外,这款软件也不要错过哦!...
- 不小心删了sxos文件夹_如何恢复Mac废纸篓删除的文件
- matlab程序及C语言实现一维多元离散信源熵
- 信息论Matlab仿真——信源熵
- office2007每次打开都配置进度_每次打开excel2007都要配置进度怎么办?